package net.wofly.sale.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import net.wofly.cashier.order.util.PayType;
import net.wofly.common.condition.Condition;
import net.wofly.common.condition.ConditionRelate;
import net.wofly.common.condition.ConditionUtil;
import net.wofly.common.condition.FilterCondition;
import net.wofly.common.condition.Operation;
import net.wofly.common.json.XiNiaoJSON;
import net.wofly.common.pay.service.PayService;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.CalcUtil;
import net.wofly.common.util.CommonStatus;
import net.wofly.common.util.FileTypeAddress;
import net.wofly.common.util.GeneralHelper;
import net.wofly.common.util.Identities;
import net.wofly.common.util.PageHelper;
import net.wofly.framework.util.ResultCode;
import net.wofly.framework.util.ReturnBean;
import net.wofly.right.domain.Customer;
import net.wofly.right.domain.Organization;
import net.wofly.right.domain.ReceivingAddr;
import net.wofly.right.domain.Role;
import net.wofly.right.domain.User;
import net.wofly.right.service.ICustomerService;
import net.wofly.right.service.IOrganizationService;
import net.wofly.right.service.IReceivingAddrService;
import net.wofly.right.service.IUserRoleService;
import net.wofly.right.service.IUserService;
import net.wofly.right.util.RoleEnum;
import net.wofly.sale.activity.domain.Activity;
import net.wofly.sale.activity.domain.ActivityGift;
import net.wofly.sale.activity.service.IActivityService;
import net.wofly.sale.activity.util.ActivityStatus;
import net.wofly.sale.activity.util.ActivityType;
import net.wofly.sale.activity.util.GiftRelateType;
import net.wofly.sale.commodity.domain.ChannelCommodityTerminalMapping;
import net.wofly.sale.commodity.domain.Commodity;
import net.wofly.sale.commodity.domain.CommodityChannel;
import net.wofly.sale.commodity.domain.CommodityTerminal;
import net.wofly.sale.commodity.domain.OrderTypeChannelMapping;
import net.wofly.sale.commodity.domain.RoleDefaultOrderType;
import net.wofly.sale.commodity.service.IChannelCommodityTmlMappingService;
import net.wofly.sale.commodity.service.ICommodityChannelService;
import net.wofly.sale.commodity.service.ICommodityService;
import net.wofly.sale.commodity.service.ICommodityTmlService;
import net.wofly.sale.commodity.service.IOrderTypeChannelMappingService;
import net.wofly.sale.commodity.service.IRoleDefaultOrderTypeService;
import net.wofly.sale.commodity.util.Channel;
import net.wofly.sale.order.OrderConfig;
import net.wofly.sale.order.domain.Gift;
import net.wofly.sale.order.domain.Introducer;
import net.wofly.sale.order.domain.Order;
import net.wofly.sale.order.domain.OrderActivity;
import net.wofly.sale.order.domain.OrderContent;
import net.wofly.sale.order.domain.OrderPublishActivityMapping;
import net.wofly.sale.order.domain.OrderReceivingAddr;
import net.wofly.sale.order.domain.OrderStatusDto;
import net.wofly.sale.order.domain.PayInfo;
import net.wofly.sale.order.domain.PayInfoPic;
import net.wofly.sale.order.domain.TakeGoodsShopInfo;
import net.wofly.sale.order.dto.req.BanquetOrderReq;
import net.wofly.sale.order.dto.req.CommodityTmlDto;
import net.wofly.sale.order.dto.req.NoMoneyOrderReq;
import net.wofly.sale.order.dto.req.ReturnGoodsOrderReq;
import net.wofly.sale.order.dto.resp.ReturnGoodsDtoResp;
import net.wofly.sale.order.flow.IOrderFlowService;
import net.wofly.sale.order.repository.SaleOrderRepository;
import net.wofly.sale.order.service.IGiftService;
import net.wofly.sale.order.service.IIntroducerService;
import net.wofly.sale.order.service.IOrderActivityService;
import net.wofly.sale.order.service.IOrderPublishActivityMappingService;
import net.wofly.sale.order.service.IOrderReceivingAddrService;
import net.wofly.sale.order.service.IOrderTypeService;
import net.wofly.sale.order.service.IPayInfoPicService;
import net.wofly.sale.order.service.IPayInfoService;
import net.wofly.sale.order.service.IReturnSalesContentService;
import net.wofly.sale.order.service.IRoleOrderTypeService;
import net.wofly.sale.order.service.ISaleOrderContentService;
import net.wofly.sale.order.service.ISaleOrderService;
import net.wofly.sale.order.service.ITakeGoodsShopInfoService;
import net.wofly.sale.order.util.GoodTransportType;
import net.wofly.sale.order.util.OrderStatus;
import net.wofly.sale.order.util.OrderType;
import net.wofly.sale.order.util.OrderUtil;
import net.wofly.sale.order.util.PlaceOrderType;
import net.wofly.sale.shoppingcart.service.ICartListService;
import net.wofly.sale.shoppingcart.util.ShoppingCartType;
import net.wofly.sale.stock.domain.InOutStockDetail;
import net.wofly.sale.stock.domain.InStock;
import net.wofly.sale.stock.domain.OutStock;
import net.wofly.sale.stock.domain.Stock;
import net.wofly.sale.stock.service.IOutStockService;
import net.wofly.sale.stock.service.IStockService;
import net.wofly.sale.stock.util.InStockType;
import net.wofly.sale.stock.util.OutStockType;
import org.apache.commons.collections.CollectionUtils;
import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;


@Service("iSaleOrderService")
@Transactional
public class SaleOrderServiceImpl implements ISaleOrderService {
    
    private final String COMMA_SIGN = ",";
    Logger logger = LoggerFactory.getLogger(SaleOrderServiceImpl.class);
    @Autowired
    IOrderFlowService iOrderFlowService;
    @Autowired
    ICommodityTmlService iCommodityTerminalService;
    @Autowired
    IReturnSalesContentService iReturnSalesContentService;
    @Autowired
    private OrderConfig orderConfig;
    @Autowired
    private SaleOrderRepository saleOrderRepository;
    @Autowired
    private ICommodityChannelService iCommodityChannelService;
    @Autowired
    private IReceivingAddrService iReceivingAddrService;
    @Autowired
    private ICommodityService iCommodityService;
    @Autowired
    private IUserService iUserService;
    @Autowired
    private PayService payService;
    @Autowired
    private IActivityService iActivityService;
    @Autowired
    private ICartListService iCartListService;
    @Autowired
    private IStockService iStockService;
    @Autowired
    private IUserRoleService iUserRoleService;
    @Autowired
    private IIntroducerService iIntroducerService;
    @Autowired
    private IPayInfoService iPayInfoService;
    @Autowired
    private IOrderReceivingAddrService iOrderReceivingAddrService;
    @Autowired
    private ITakeGoodsShopInfoService iTakeGoodsShopInfoService;
    @Autowired
    private IOrganizationService iOrganizationService;
    @Autowired
    private IOrderTypeService iOrderTypeService;
    @Autowired
    private IRoleOrderTypeService iRoleOrderTypeService;
    @Autowired
    private IOrderTypeChannelMappingService iOrderTypeChannelMappingService;
    @Autowired
    private ICommodityTmlService iCommodityTmlService;
    @Autowired
    private IChannelCommodityTmlMappingService iChannelCommodityTmlMappingService;
    @Autowired
    private IRoleDefaultOrderTypeService iRoleDefaultOrderTypeService;
    @Autowired
    private IPayInfoPicService iPayInfoPicService;
    @Autowired
    private IOutStockService iOutStockService;
    @Autowired
    private IGiftService iGiftService;
    @Autowired
    private IOrderActivityService iOrderActivityService;
    @Autowired
    private IOrderPublishActivityMappingService iOrderPublishActivityMappingService;
    @Autowired
    private ICustomerService iCustomerService;
    @Autowired
    private ISaleOrderContentService iSaleOrderContentService;
    
    @Override
    public Order save(Order entity) {
        return saleOrderRepository.save(entity);
    }
    
    @Override
    public void delete(Order entity) {
        saleOrderRepository.delete(entity);
    }
    
    @Override
    public void delete(String key) {
        saleOrderRepository.delete(key);
    }
    
    @Override
    public Order findOne(String key) {
        return saleOrderRepository.findOne(key);
    }
    
    @Override
    public Object findMaxOrderNoByDate(String dateStr) {
        return saleOrderRepository.findMaxOrderNoByDate(dateStr);
    }
    
    @Override
    public List<Order> save(List<Order> entityList) {
        return (List<Order>) saleOrderRepository.save(entityList);
    }
    
    @Override
    public Page<Order> findAll(Specification specification, Pageable pageable) {
        return saleOrderRepository.findAll(specification, pageable);
    }
    
    @Override
    public List<Order> findByInProcessInsID(List<String> processInsIDs) {
        return saleOrderRepository.findByProcessInsIDIn(processInsIDs);
    }
    
    @Override
    public Order findByProcessInsID(String processInsID) {
        return saleOrderRepository.findByProcessInsID(processInsID);
    }
    
    @Override
    public ReturnBean<Order> createOrder(Order order) throws CloneNotSupportedException {
        String orderID = Identities.uuid2();
        Long modifyDate = System.currentTimeMillis();
        order.setOrderID(orderID);
        
        // 先校验库存 后 处理礼品  --> 要先处理礼品信息，在校验库存，因为赠品也需要减库存，并且支付方式是白条支付的订单赠品不减库存
        // 判断是自助下单，还是代下单
        User buyer = iUserService.findOne(order.getBuyer());
        if (buyer == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), "下单人buyerID不正确，未找到对应用户");
        }
        
        List<Role> roles = iUserRoleService.findRolesByUserID(order.getBuyer());
        if (CollectionUtils.isEmpty(roles)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), "下单人buyerID对应的角色不存在，暂时不能下单");
        }
        
        //暂时考虑一个用户只有一个角色
        Role role = roles.get(0);
        //设置orderType
        if (role.getRoleID().startsWith("1")) {
            //待客下单 ，支付凭证不能为空
            if (validatePayInfoPics(order)) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), "代下订单，支付凭证不能为空不能为空");
            }
            //员工
            if (OrderType.无款订单.getValue().intValue() == order.getOrderType()) {
                //TODO Q: 内欠订单是否是自助下单 ，目前按excel 表格中实现是自助下单， 需要确认
                order.setPlaceOrderType(PlaceOrderType.自助下单.getValue());
            } else {
                if (StringUtils.isEmpty(order.getCustomerUserID())) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), "代下订单，客户ID不能为空");
                }
                order.setPlaceOrderType(PlaceOrderType.代客下单.getValue());
            }
            order.setSalerID(order.getBuyer());
        } else {
            order.setPlaceOrderType(PlaceOrderType.自助下单.getValue());
            order.setSalerID(buyer.getFollowUserID());
        }
        
        if (PlaceOrderType.代客下单.getValue().intValue() == order.getPlaceOrderType()) {
            if (order.getPayType() == null || !PayType.isValueCorrect(order.getPayType())) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), "订单支付类型不能为空，或者订单支付类型不正确");
            }
        }
        
        //处理订单信息，主要是结合活动计算礼品  礼品是和活动一起的， 有活动才有礼品
        ReturnBean<Order> res = handleOrder(order, orderID);
        if (res.getCode() != ResultCode.SUCCESS.intValue()) {
            return new ReturnBean<>(res.getCode(), res.getMsg());
        }
        
        Map<String, Integer> terminalStockMap = new HashMap<>();
        Map<String, String> terminaleNameMap = new HashMap<>();
        Map<String, String> terminalMsgMap = new HashMap<>();
        //①遍历订单详情的正品、赠品、订单的赠品，进行出库（入库）明细的累加
        for (OrderContent orderContent : order.getOrderContents()) {
            //正品的数量
            CommodityTerminal commodityTerminal = getCommodityTerminal(String.valueOf(order.getOrderType()),
                    orderContent.getCommodityChannelID());
            if (StringUtils.isEmpty(commodityTerminal.getCommodityTerminalID())) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), commodityTerminal.getConfigWarnMsg());
            }
            String terminalID = commodityTerminal.getCommodityTerminalID();
            //设置终端id后续逻辑会用到 提示语  --> 2018.5.27新需求，需要入库
            orderContent.setCommodityTerminalID(terminalID);
            if (null == terminalStockMap.get(terminalID)) {
                terminalStockMap.put(terminalID, orderContent.getNum());
                //设置商品的名称
                terminaleNameMap.put(terminalID,
                        orderContent.getCommodity() != null ? orderContent.getCommodity().getCommodityName() :
                                orderContent.getCommodityChannelID());
            } else {
                terminalStockMap.put(terminalID, terminalStockMap.get(terminalID) + orderContent.getNum());
            }
            //非白条支付的减赠品的库存，白条支付的不减赠品的库存
            if (null != order.getPayType() && PayType.白条支付.getValue().intValue() != order.getPayType()) {
                //订单内容中商品对应的赠品 数量处理
                List<ActivityGift> activityGifts = orderContent.getActivityGifts();
                sumTerminalStockNum(terminalStockMap, terminaleNameMap, activityGifts);
            }
        }
        //②再处理订单的赠品，进行出库（入库）明细的累加
        //非白条支付的减赠品的库存，白条支付的不减赠品的库存
        if (null != order.getPayType() && PayType.白条支付.getValue().intValue() != order.getPayType()) {
            List<ActivityGift> orderActivityGifts = order.getActivityGifts();
            sumTerminalStockNum(terminalStockMap, terminaleNameMap, orderActivityGifts);
        }
        
        //此处再处理库存是否充足问题，正品和赠品库存不足时，都不能下单
        //库存不足提示，默认false ，即默认为库存是足够的， 不够时，提示前端
        if (OrderType.订货会流通订单.getValue().intValue() == order.getOrderType()
                || OrderType.订货会酒店订单.getValue().intValue() == order.getOrderType()) {
            handleStock4ReturnGoodOrder(order, orderID, modifyDate, terminalStockMap);
            
        } else {
            //非订货会订单减库存
            ReturnBean<Order> returnBean = handleStock(order, orderID, modifyDate, buyer, role, terminalStockMap,
                    terminaleNameMap, terminalMsgMap);
            if (returnBean != null) {
                return returnBean;
            }
        }
        
        //处理订单赠品信息
        handleGiftsInfo(order, orderID, res);
        
        ReturnBean<Order> returnBean = handleOrderReceiveAddrAndTakeGoodsInfo(order, orderID, modifyDate, buyer);
        if (returnBean != null) {
            return returnBean;
        }
        
        if (order.getPlaceOrderType().intValue() == PlaceOrderType.自助下单.getValue()) {
            order.setCustomerUserID(order.getBuyer());
        }
        
        order.setOrderCommitTime(modifyDate);
        
        // 介绍人
        Introducer introducer = order.getIntroducer();
        if (introducer != null) {
            introducer.setIntroducerID(Identities.uuid2());
            introducer.setOrderID(orderID);
            introducer.setModifyDate(System.currentTimeMillis());
            //iIntroducerService.save(introducer);
        }
        
        if (!OrderType.还货订单.getValue().equals(order.getOrderType())
                && !OrderType.无款订单.getValue().equals(order.getOrderType())) {
            //设置订单的付款截止时间
            order.setPayDeadline(System.currentTimeMillis() + orderConfig.getTimeout() * 60 * 60 * 1000);
        }
        
        if (OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
            order.setStatus(OrderStatus.订单己支付.getValue());
        } else {
            order.setStatus(OrderStatus.订单提交_未支付.getValue());
        }
        
        //生成订单编号
        String orderNO = generateOrderNO();
        order.setOrderNo(orderNO);
        
        //设置支付状态
        if (null != order.getPayType()) {
            if (PayType.白条支付.getValue().intValue() == order.getPayType()) {
                order.setStatus(OrderStatus.白条已支付.getValue());
            } else if (PayType.支付定金.getValue().intValue() == order.getPayType()) {
                order.setStatus(OrderStatus.支付定金.getValue());
            } else {
                order.setStatus(OrderStatus.订单己支付.getValue());
            }
        }
        
        //处理支付凭证信息
        handlePayInfoPics(order, modifyDate);
        
        save(order);
        
        //保存订单对应的活动信息
        saveOrderActivities(order, modifyDate);
        //保存此刻发布中的所有订单满赠的活动列表（供退货用）
        saveOrderPublishActivities(order, modifyDate);
        
        // 删除购物车  直接根据人处理  根据人删除 , 购物车是当前登录人的购物车
        iCartListService.deleteByShoppingCartIDAndShoppingCartType(order.getBuyer(), ShoppingCartType.购物车.getValue());
        
        if (null != order.getPayDeadline()) {
            //设置订单的剩余支付时间
            order.setPayRestTime(order.getPayDeadline() - System.currentTimeMillis());
        }
        
        return new ReturnBean<>(ResultCode.SUCCESS, "订单创建成功", order);
    }
    
    /**
     * 保存订单对应的活动信息
     *
     * @param order
     */
    private void saveOrderActivities(Order order, long modifyDate) {
        List<OrderActivity> orderActivityList = new ArrayList<>();
        //处理订单内容的活动ID
        Set<String> orderContentActivitySet = new HashSet<>();
        for (OrderContent orderContent : order.getOrderContents()) {
            if (CollectionUtils.isNotEmpty(orderContent.getActivityGifts())) {
                for (ActivityGift activityGift : orderContent.getActivityGifts()) {
                    orderContentActivitySet.add(activityGift.getActivityID());
                }
            }
        }
        for (String activityID : orderContentActivitySet) {
            OrderActivity orderActivity = new OrderActivity();
            orderActivity.setOrderActivityID(Identities.uuid2());
            orderActivity.setOrderID(order.getOrderID());
            orderActivity.setActivityID(activityID);
            orderActivity.setRelateType(GiftRelateType.订单内商品.getValue());
            orderActivity.setModifyDate(modifyDate);
            orderActivityList.add(orderActivity);
        }
        
        //处理订单的活动ID
        Set<String> orderActivitySet = new HashSet<>();
        if (CollectionUtils.isNotEmpty(order.getActivityGifts())) {
            for (ActivityGift activityGift : order.getActivityGifts()) {
                orderActivitySet.add(activityGift.getActivityID());
            }
        }
        for (String activityID : orderActivitySet) {
            OrderActivity orderActivity = new OrderActivity();
            orderActivity.setOrderActivityID(Identities.uuid2());
            orderActivity.setOrderID(order.getOrderID());
            orderActivity.setActivityID(activityID);
            orderActivity.setRelateType(GiftRelateType.订单.getValue());
            orderActivity.setModifyDate(modifyDate);
            orderActivityList.add(orderActivity);
        }
        iOrderActivityService.save(orderActivityList);
    }
    
    /**
     * 保存此刻发布中的所有订单满赠的活动列表（供退货用）
     *
     * @param order
     */
    private void saveOrderPublishActivities(Order order, Long modifyDate) {
        //查询所有发布中的活动列表
        List<Activity> activities = iActivityService
                .findByActivityTypeAndStatusAndStartTimeBeforeAndEndTimeAfter(
                        ActivityType.单一订单中商品总价.getValue(), ActivityStatus.发布.getValue(), modifyDate, modifyDate);
        
        if (CollectionUtils.isNotEmpty(activities)) {
            //处理并保存所有发布中的活动列表
            List<OrderPublishActivityMapping> mappingList = new ArrayList<>();
            for (Activity activity : activities) {
                OrderPublishActivityMapping mapping = new OrderPublishActivityMapping();
                mapping.setOrderPublishActivityMappingID(Identities.uuid2());
                mapping.setOrderID(order.getOrderID());
                mapping.setActivityID(activity.getActivityID());
                mapping.setModifyDate(modifyDate);
                mappingList.add(mapping);
            }
            iOrderPublishActivityMappingService.save(mappingList);
        }
    }
    
    /**
     * 处理支付凭证信息
     *
     * @param order
     * @param modifyDate
     */
    private void handlePayInfoPics(Order order, Long modifyDate) {
        int i = 0;
        if (CollectionUtils.isNotEmpty(order.getPayInfoPics())) {
            for (PayInfoPic payInfoPic : order.getPayInfoPics()) {
                payInfoPic.setOrderID(order.getOrderID());
                payInfoPic.setOrderPayInfoPicID(Identities.uuid2());
                payInfoPic.setSequenceNumber(i++);
                payInfoPic.setImgType(FileTypeAddress.支付单据图片.getValue());
                payInfoPic.setModifyDate(modifyDate);
            }
        }
    }
    
    /**
     * 校验支付凭证是否为空
     *
     * @param order
     * @return
     */
    private boolean validatePayInfoPics(Order order) {
        //待客下单 ，支付凭证不能为空
        if (CollectionUtils.isEmpty(order.getPayInfoPics())) {
            return true;
        }
        for (PayInfoPic payInfoPic : order.getPayInfoPics()) {
            if (StringUtils.isEmpty(payInfoPic.getImgUrl())) {
                return true;
            }
        }
        return false;
    }
    
    
    /**
     * 处理订单赠品信息
     *
     * @param order
     * @param orderID
     * @param res
     */
    private void handleGiftsInfo(Order order, String orderID, ReturnBean<Order> res) {
        // 订单的礼品总数量
        int totalCommodityNum = 0;
        int totalGiftNum = 0;
        
        List<Gift> orderGiftSet = new ArrayList<>();
        // 商品GIFT
        List<OrderContent> orderContents = res.getResult().getOrderContents();
        for (OrderContent content : orderContents) {
            List<Gift> contentGifts = new ArrayList<>();
            List<ActivityGift> activityGifts = content.getActivityGifts();
            if (CollectionUtils.isNotEmpty(activityGifts)) {
                for (ActivityGift activityGift : activityGifts) {
                    totalGiftNum += activityGift.getNum();
                    Gift gift = new Gift();
                    gift.setGiftID(Identities.uuid2());
                    gift.setModifyDate(System.currentTimeMillis());
                    gift.setActivityID(activityGift.getActivityID());
                    gift.setActivityGiftID(activityGift.getActivityGiftID());
                    //gift.setCommodityChannelID(content.getCommodityChannelID());
                    gift.setCommodityTerminalID(activityGift.getCommodityTerminalID());
                    gift.setNum(activityGift.getNum());
                    gift.setRelateType(GiftRelateType.订单内商品.getValue());
                    gift.setRelateID(content.getOrderContentID());
                    gift.setOrderID(orderID);
                    gift.setOrderContentID(content.getOrderContentID());
                    contentGifts.add(gift);
                }
                content.setGifts(contentGifts);
            }
            content.setPreorderNum(content.getNum());
            totalCommodityNum += content.getNum();
        }
        order.setCommodityTotalNum(totalCommodityNum);
        //订单GIFT
        List<ActivityGift> activityGifts = res.getResult().getActivityGifts();
        if (CollectionUtils.isNotEmpty(activityGifts)) {
            for (ActivityGift activityGift : activityGifts) {
                totalGiftNum += activityGift.getNum();
                Gift gift = new Gift();
                gift.setGiftID(Identities.uuid2());
                gift.setModifyDate(System.currentTimeMillis());
                gift.setActivityGiftID(activityGift.getActivityGiftID());
                gift.setNum(activityGift.getNum());
                gift.setRelateType(GiftRelateType.订单.getValue());
                gift.setCommodityTerminalID(activityGift.getCommodityTerminalID());
                gift.setRelateID(order.getOrderID());
                gift.setOrderID(orderID);
                orderGiftSet.add(gift);
            }
        }
        
        order.setGiftNum(totalGiftNum);
        //  GIFT 表插入数据
        order.setGifts(orderGiftSet);
    }
    
    /**
     * 处理订单的收货地址或提货门店信息
     *
     * @param order
     * @param orderID
     * @param modifyDate
     * @param buyer
     * @return
     */
    private ReturnBean<Order> handleOrderReceiveAddrAndTakeGoodsInfo(
            Order order, String orderID, Long modifyDate, User buyer) {
        if (order.getPlaceOrderType() == PlaceOrderType.代客下单.getValue().intValue()) {
            if (OrderType.会员订单.getValue().intValue() == order.getOrderType()
                    || OrderType.签单订单.getValue().intValue() == order.getOrderType()
                    || OrderType.宴会订单.getValue().intValue() == order.getOrderType()) {
                order.setGoodTransportType(GoodTransportType.门店自取.getValue());
            } else {
                order.setGoodTransportType(GoodTransportType.送货上门.getValue());
            }
        } else {
            //自助下单必须选门店
            if (null == order.getTakeGoodsShopInfo() && OrderType.无款订单.getValue() != order.getOrderType().intValue()) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "取货门店不能为空");
            }
        }
        
        if (GoodTransportType.送货上门.getValue().intValue() == order.getGoodTransportType()) {
            //收地地址
            OrderReceivingAddr orderReceivingAddr = order.getOrderReceivingAddr();
            if (orderReceivingAddr == null) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "收货地址不能为空");
            }
            ReceivingAddr receivingAddr = iReceivingAddrService.findOne(orderReceivingAddr.getReceivingAddrID());
            if (receivingAddr == null) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "收货地址ID不正确");
            }
            orderReceivingAddr.setOrderID(orderID);
            orderReceivingAddr.setOrderReceivingAddrID(Identities.uuid2());
            orderReceivingAddr.setModifyDate(modifyDate);
            orderReceivingAddr.setReceivingAddr(receivingAddr);
            iOrderReceivingAddrService.save(orderReceivingAddr);
            order.setOrderReceivingAddr(orderReceivingAddr);
        } else {
            TakeGoodsShopInfo takeGoodsShopInfo = order.getTakeGoodsShopInfo();
            if (null == takeGoodsShopInfo) {
                takeGoodsShopInfo = new TakeGoodsShopInfo();
                //代客下单 门店为空时，后台自动设置为销售的所属门店
                takeGoodsShopInfo.setShopOrgID(buyer.getOrganizationID());
            }
            takeGoodsShopInfo.setTakeGoodsShopInfoID(Identities.uuid2());
            takeGoodsShopInfo.setOrderID(orderID);
            takeGoodsShopInfo.setModifyDate(System.currentTimeMillis());
            iTakeGoodsShopInfoService.save(takeGoodsShopInfo);
            
            Organization organization = iOrganizationService.findOne(takeGoodsShopInfo.getShopOrgID());
            takeGoodsShopInfo.setOrganization(organization);
            order.setTakeGoodsShopInfo(takeGoodsShopInfo);
        }
        return null;
    }
    
    /**
     * 非订货会订单减库存处理
     *
     * @param order
     * @param orderID
     * @param modifyDate
     * @param buyer
     * @param role
     * @param terminalStockMap
     * @param terminaleNameMap
     * @param terminalMsgMap
     * @return
     */
    private ReturnBean<Order> handleStock(
            Order order, String orderID, Long modifyDate, User buyer, Role role, Map<String, Integer> terminalStockMap,
            Map<String, String> terminaleNameMap, Map<String, String> terminalMsgMap) {
        String wareHouseIDs = getWarehouseID(order, buyer, role);
        if (StringUtils.isEmpty(wareHouseIDs)) {
            logger.info(">>> 未找到对应的仓库信息，不能下单");
            return new ReturnBean<>(ResultCode.ERROR_SERVICE.intValue(), "未找到对应的仓库信息，暂时不能下单");
        }
        boolean warningFlag = false;
        // 出库
        OutStock outStock = new OutStock();
        outStock.setOutStockID(Identities.uuid2());
        outStock.setWarehouseID(wareHouseIDs);
        outStock.setOutStockType(OutStockType.订单出库.getValue());
        outStock.setProofID(orderID);
        outStock.setOutStocker(order.getBuyer());
        outStock.setModifyDate(modifyDate);
        List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
        Iterator<Map.Entry<String, Integer>> iterator = terminalStockMap.entrySet().iterator();
        //还货订单是减销售和客户的虚拟库存，其他都是只减一个库存，此处只减第一个，因为还货订单是新加了单独的接口
        String wareHouseID = wareHouseIDs.split(COMMA_SIGN)[0];
        while (iterator.hasNext()) {
            Map.Entry<String, Integer> entry = iterator.next();
            String commodityTerminalID = entry.getKey();
            Integer num = entry.getValue();
            Stock stock = iStockService.findByWarehouseIDAndCommodityTerminalID(wareHouseID, commodityTerminalID);
            if (stock != null) {
                if (stock.getNum() >= entry.getValue()) {
                    //flag1
                    //OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails, commodityTerminalID, num);
                } else if (stock.getNum() < num) {
                    logger.info(terminaleNameMap.get(
                            commodityTerminalID) + "库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                    // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                    terminalMsgMap.put(commodityTerminalID, "库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                    warningFlag = true;
                }
            } else {
                logger.info(terminaleNameMap.get(commodityTerminalID) + "库存不足，下单数量" + num + "，库存数量0");
                // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                terminalMsgMap.put(commodityTerminalID, "库存不足，下单数量" + num + "，库存数量0");
                warningFlag = true;
            }
            //库存允许为负数，所以此行代码放在这里执行，注释掉flag1处的代码
            OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails, commodityTerminalID, num);
        }
        
        if (warningFlag && orderConfig.isCheckStock()) {
            //先注释以下代码，不进行强制校验，需要前端配合 调试后放开
            String msg = "部分商品库存不足，请重新检查数量下单";
            if (OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
                msg = "业务员的库存中" + msg;
            }
            
            //处理订单正品和赠品库存不足提示语
            for (OrderContent orderContent : order.getOrderContents()) {
                orderContent.setStockLackMsg(terminalMsgMap.get(orderContent.getCommodityTerminalID()));
                //处理订单赠品库存不足提示语
                if (CollectionUtils.isNotEmpty(orderContent.getActivityGifts())) {
                    for (ActivityGift activityGift : orderContent.getActivityGifts()) {
                        //活动赠品改为终端商品
                        activityGift.setStockLackMsg(terminalMsgMap.get(activityGift.getCommodityTerminalID()));
                    }
                }
            }
            //处理订单赠品库存不足提示语
            if (CollectionUtils.isNotEmpty(order.getActivityGifts())) {
                for (ActivityGift activityGift : order.getActivityGifts()) {
                    //活动赠品改为终端商品
                    activityGift.setStockLackMsg(terminalMsgMap.get(activityGift.getCommodityTerminalID()));
                }
            }
            return new ReturnBean<>(ResultCode.ERROR_SERVICE_NOT_ENOUGH.intValue(), msg, order);
        }
        outStock.setInOutStockDetails(inOutStockDetails);
        iStockService.addOutStock(outStock);
        return null;
    }
    
    /**
     * 处理订货会订单的库存（订货会，不需要减库存）
     *
     * @param order
     * @param orderID
     * @param modifyDate
     * @param terminalStockMap
     */
    private void handleStock4ReturnGoodOrder(
            Order order, String orderID, Long modifyDate, Map<String, Integer> terminalStockMap) {
        //订货会订单不减库存，需要给客户创建虚拟库存，便于以后还货订单时减客户的库存
        if (CollectionUtils.isNotEmpty(order.getOrderContents())) {
            // 入库
            InStock inStock = new InStock();
            inStock.setInStockType(InStockType.订货会订单.getValue());
            inStock.setInStocker(order.getBuyer());
            inStock.setProofID(orderID);
            inStock.setWarehouseID(order.getCustomerUserID());
            inStock.setModifyDate(modifyDate);
            //入库流水，包括正品和赠品
            List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
            Iterator<Map.Entry<String, Integer>> iterator = terminalStockMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> next = iterator.next();
                OrderUtil.buildInOutStockDetail(modifyDate, inOutStockDetails, next.getKey(),
                        next.getValue());
            }
            inStock.setInOutStockDetails(inOutStockDetails);
            iStockService.addInStock(inStock);
        }
    }
    
    /**
     * 为订单内容的正品及赠品，订单赠品，计算各自商品终端出入库明细的累加数量
     *
     * @param tmlStockMap
     * @param orderActivityGifts
     */
    private void sumTerminalStockNum(
            Map<String, Integer> tmlStockMap, Map<String, String> terminaleNameMap,
            List<ActivityGift> orderActivityGifts) {
        if (CollectionUtils.isNotEmpty(orderActivityGifts)) {
            for (ActivityGift activityGift : orderActivityGifts) {
                //活动赠品改为终端商品
                String terminalIDGift = activityGift.getCommodityTerminalID();
                if (null == tmlStockMap.get(terminalIDGift)) {
                    tmlStockMap.put(terminalIDGift, activityGift.getNum());
                    //活动赠品改为终端商品
                    terminaleNameMap.put(terminalIDGift,
                            activityGift.getCommodity() != null ? activityGift.getCommodity().getCommodityName()
                                    : activityGift.getCommodityTerminalID());
                } else {
                    tmlStockMap.put(terminalIDGift, tmlStockMap.get(terminalIDGift) + activityGift.getNum());
                }
            }
        }
    }
    
    private String generateOrderNO() {
        String orderNum;
        String dateStr = LocalDate.now().toString("yyyyMMdd");
        Object maxOrderNoByDate = findMaxOrderNoByDate(dateStr);
        if (!StringUtils.isEmpty(maxOrderNoByDate)) {
            Long orderNo = Long.valueOf(dateStr + maxOrderNoByDate.toString()) + 1;
            orderNum = String.valueOf(orderNo);
        } else {
            orderNum = dateStr + "0001";
        }
        return orderNum;
    }
    
    @Override
    public CommodityTerminal getCommodityTerminal(String orderType, String commodityChannelID) {
        CommodityTerminal commodityTerminal = new CommodityTerminal();
        CommodityChannel commodityChannel = iCommodityChannelService.findOne(commodityChannelID);
        
        //根据订单类型找到channel
        OrderTypeChannelMapping orderTypeChannelMapping = iOrderTypeChannelMappingService.findByOrderType(orderType);
        if (null == orderTypeChannelMapping) {
            logger.info(">>> 未找到订单类型和渠道的关系配置数据...");
            commodityTerminal.setConfigWarnMsg("未找到订单类型和渠道的关系配置数据");
            return commodityTerminal;
        }
        ChannelCommodityTerminalMapping channelCommodityTerminalMapping = iChannelCommodityTmlMappingService
                .findByChannel(orderTypeChannelMapping.getChannel());
        if (null == channelCommodityTerminalMapping) {
            logger.info(">>> 未找到渠道和商品终端类型的关系配置数据...");
            commodityTerminal.setConfigWarnMsg("未找到渠道和商品终端类型的关系配置数据");
            return commodityTerminal;
        }
        commodityTerminal = iCommodityTmlService.findByCommodityIDAndCommodityTerminalTypeAndStatus(
                commodityChannel.getCommodityID(), channelCommodityTerminalMapping.getCommodityTerminalType(),
                CommonStatus.有效.getValue());
        if (null == commodityTerminal) {
            logger.info(">>> 未找到商品终端的数据...");
            commodityTerminal.setConfigWarnMsg("未找到商品终端的数据");
            return commodityTerminal;
        }
        return commodityTerminal;
    }
    
    
    /**
     * 根据订单及用户角色获得仓库信息，用于减库存或者恢复库存操作
     *
     * @param order 订单
     * @param buyer 下单人（操作人）
     * @param role  下单人的角色
     * @return
     */
    private String getWarehouseIDOld(Order order, User buyer, Role role) {
        //            100	内部员工	1	0	1506438068780	0	0
        //            101	老板	1	0	1506438069926	0	0
        //            102	会计	1	0	1506438756066	0	0
        //            103	出纳	1	0	1506438882064	0	0
        //            104	库管	1	0	1506438087268	1	1
        //            105	店员	1	0	1506438069922	1	2
        //            106	业务员	1	1	1506438069922	1	3
        //            107	团购专员	1	0	1506438069922	1	3
        //            200	客户	1	0	1506438069926	0	0
        //            201	会员	1	0	1506438045915	0	0
        //            202	团购	1	0	1506438069926	0	0
        //            203	流通客户	1	0	1506438069926	0	0
        //            204	酒店客户	1	0	1506438667946	0	0
        //            205	签单	1	0	1506438044981	0	0
        String wareHouseID = null;
        if (order.getPlaceOrderType().intValue() == PlaceOrderType.自助下单.getValue()) {
            if (RoleEnum.会员客户.getValue().equals(role.getRoleID())) {
                // 会员 减店面库存，根据客户选择的发货（提货）门店确定 订单告知是哪个店面 , 才可以 ;
                TakeGoodsShopInfo takeGoodsShopInfo = order.getTakeGoodsShopInfo();
                if (null == takeGoodsShopInfo) {
                    //创建订单时不为空，查询时是为空的，主动去查
                    takeGoodsShopInfo = iTakeGoodsShopInfoService.findByOrderID(order.getOrderID());
                }
                //门店ID
                wareHouseID = takeGoodsShopInfo.getShopOrgID();
            } else if (RoleEnum.店员.getValue().equals(role.getRoleID())) {
                // 另外内欠订单是店员下单，减的是店面的库存
                wareHouseID = buyer.getOrganizationID();
            } else if (RoleEnum.流通客户.getValue().equals(role.getRoleID()) || RoleEnum.酒店客户.getValue().equals(
                    role.getRoleID())) {
                // 流通客户和酒店客户 ,减对应销售员库存
                wareHouseID = buyer.getFollowUserID();
            }
            order.setCustomerUserID(order.getBuyer());
        } else if (order.getPlaceOrderType().intValue() == PlaceOrderType.代客下单.getValue()) {
            if (RoleEnum.店员.getValue().equals(role.getRoleID())) {
                // 店员（无款订单）和 签单  , 减店面库存
                wareHouseID = buyer.getOrganizationID();
            } else if (RoleEnum.业务员.getValue().equals(role.getRoleID()) || RoleEnum.团购专员.getValue().equals(
                    role.getRoleID())) {
                // 业务员（销售）和团购 ,减对应销售员库存
                wareHouseID = buyer.getUserID();
                if (OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
                    //还货订单， 要减客户的虚拟库存和销售的库存
                    wareHouseID = order.getCustomerUserID() + COMMA_SIGN + buyer.getUserID();
                }
            }
        }
        return wareHouseID;
    }
    
    /**
     * 根据订单及用户角色获得仓库信息，用于减库存或者恢复库存操作
     *
     * @param order 订单
     * @param buyer 下单人（操作人）
     * @param role  下单人的角色
     * @return
     */
    private String getWarehouseID(Order order, User buyer, Role role) {
        //            100	内部员工	1	0	1506438068780	0	0
        //            101	老板	1	0	1506438069926	0	0
        //            102	会计	1	0	1506438756066	0	0
        //            103	出纳	1	0	1506438882064	0	0
        //            104	库管	1	0	1506438087268	1	1
        //            105	店员	1	0	1506438069922	1	2
        //            106	业务员	1	1	1506438069922	1	3
        //            107	团购专员	1	0	1506438069922	1	3
        //            200	客户	1	0	1506438069926	0	0
        //            201	会员	1	0	1506438045915	0	0
        //            202	团购	1	0	1506438069926	0	0
        //            203	流通客户	1	0	1506438069926	0	0
        //            204	酒店客户	1	0	1506438667946	0	0
        //            205	签单	1	0	1506438044981	0	0
        String wareHouseID = null;
        if (role.getRoleID().startsWith("1")) {
            //内部员工，库存直接从user表中查到，取user表中的wareHouseID即可，因为是否有仓库及仓库的ID都是在用户管理的进行维护的
            wareHouseID = buyer.getWarehouseID();
            if (OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
                //还货订单， 要减客户的虚拟库存和销售的库存，
                wareHouseID = wareHouseID + COMMA_SIGN + order.getCustomerUserID();
            }
        } else {
            if (RoleEnum.会员客户.getValue().equals(role.getRoleID()) || RoleEnum.签单客户.getValue().equals(
                    role.getRoleID())) {
                // 会员 减店面库存，根据客户选择的发货（提货）门店确定 订单告知是哪个店面 , 才可以 ;
                TakeGoodsShopInfo takeGoodsShopInfo = order.getTakeGoodsShopInfo();
                if (null == takeGoodsShopInfo) {
                    //创建订单时不为空，查询时是为空的，主动去查
                    takeGoodsShopInfo = iTakeGoodsShopInfoService.findByOrderID(order.getOrderID());
                }
                //门店ID
                wareHouseID = takeGoodsShopInfo.getShopOrgID();
            } else if (RoleEnum.流通客户.getValue().equals(role.getRoleID()) || RoleEnum.酒店客户.getValue().equals(
                    role.getRoleID())) {
                // 流通客户和酒店客户 ,减对应销售员库存
                if (StringUtils.isEmpty(buyer.getFollowUserID())) {
                    logger.info(">>> 流通客户||酒店客户 自助下单，但是未找到对应的销售员信息 ");
                } else {
                    User saler = iUserService.findOne(buyer.getFollowUserID());
                    if (saler == null) {
                        logger.info(">>> 流通客户||酒店客户 自助下单，对应的销售员信息（user表中）不存在 ");
                    } else {
                        wareHouseID = saler.getWarehouseID();
                    }
                }
            }
            order.setCustomerUserID(order.getBuyer());
        }
        return wareHouseID;
    }
    
    /**
     * 处理订单的赠品信息，提交订单之前
     *
     * @param order
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    public ReturnBean<Order> handleOrder(Order order) throws CloneNotSupportedException {
        return handleOrder(order, "");
    }
    
    private ReturnBean<Order> handleOrder(Order order, String orderID) throws CloneNotSupportedException {
        Long modifyDate = System.currentTimeMillis();
        int totalNum = 0;
        // 总价
        Double totalAmount = 0.0;
        //活动总价
        Double totalActivityAmount = 0.0;
        Integer totalGiftNum = 0;
        
        // 判断订单类型不能为空
        if (order.getOrderType() == null || !OrderType.isValueCorrect(order.getOrderType())) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单类型不能为空或者订单类型不正确");
        }
        
        //订单内容 、 商品活动、 订单活动
        
        //计算订单礼品要考虑4个维度 ①商品类型 ②活动类型 ③订单类型  ④数量（num 或者 amount）
        List<OrderContent> orderContents = order.getOrderContents();
        for (OrderContent orderContent : orderContents) {
            //需要重新计算赠品，先将原来的赠品处理掉
            orderContent.setActivityGifts(null);
            CommodityChannel commodityChannel = iCommodityChannelService.findOne(orderContent.getCommodityChannelID());
            if (null == commodityChannel) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单内容的商品渠道ID不正确");
            }
            
            //商品赠品
            List<ActivityGift> activityGifts = new ArrayList<>();
            
            // 此处考虑活动价格   //查询有效的活动信息
            List<Activity> activityList = iActivityService
                    .findByCommodityChannelIDAndStatusAndStartTimeBeforeAndEndTimeAfter(
                            orderContent.getCommodityChannelID(), ActivityStatus.发布.getValue(), modifyDate, modifyDate);
            
            if (CollectionUtils.isNotEmpty(activityList)) {
                for (Activity activity : activityList) {
                    Integer orderType = activity.getOrderType();
                    if (orderType.intValue() == -1) {
                        // 适用于所有订单
                        getChannelActivityGifts(orderContent, commodityChannel, activityGifts, activity);
                    } else {// 指定类型的订单
                        if (orderType.intValue() == order.getOrderType()) {
                            getChannelActivityGifts(orderContent, commodityChannel, activityGifts, activity);
                        }
                    }
                }
            }
            
            totalAmount = CalcUtil.add(totalAmount,
                    CalcUtil.mul(commodityChannel.getCommodityChannelPrise(), orderContent.getNum()));
            totalNum += orderContent.getNum();
            
            orderContent.setPrice(commodityChannel.getCommodityChannelPrise());
            orderContent.setTotalPrice(
                    CalcUtil.mul(commodityChannel.getCommodityChannelPrise(), orderContent.getNum()));
            
            orderContent.setOrderID(orderID);
            orderContent.setModifyDate(modifyDate);
            orderContent.setOrderContentID(Identities.uuid2());
        }
        
        //设置订单的相关信息
        //购买商品的数量
        order.setCommodityNum(totalNum);
        // 商品总价
        order.setAmount(totalAmount);
        //活动商品总价  暂时=商品总价 ，因为活动 只有赠品，没有打折了 实际应该应是totalActivityAmount, 打折之后的价格
        totalActivityAmount = totalAmount;
        order.setActivityAmount(totalActivityAmount);
        // 订单优惠价 等于商品总价-活动总价
        order.setOrderDiscounts(CalcUtil.sub(order.getAmount(), order.getActivityAmount()));
        // 实收 活动价-支付优惠
        order.setRealPrice(CalcUtil.sub(order.getActivityAmount(), order.getPayDiscounts()));
        
        if (OrderType.无款订单.getValue().intValue() == order.getOrderType()
                || OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
            order.setRealPrice(0.0);
        }
        
        // 订单的活动信息
        getOrderActivityGifts(order, modifyDate);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "success", order);
    }
    
    private void getOrderActivityGifts(Order order, long modifyDate) {
        List<ActivityGift> orderActivityGiftList = new ArrayList<>();
        //   订单的活动 两种方式 , 查询订单的活动时，要加上活动的状态、起止时间进程查询
        List<Activity> activities = iActivityService.findByActivityTypeAndStatusAndStartTimeBeforeAndEndTimeAfter(
                ActivityType.单一订单中商品数量.getValue(), ActivityStatus.发布.getValue(), modifyDate, modifyDate);
        if (CollectionUtils.isNotEmpty(activities)) {
            for (Activity activity : activities) {
                if (activity.getOrderType().intValue() == -1) {
                    if (order.getCommodityNum() >= activity.getNum()) {
                        orderActivityGiftList.addAll(activity.getActivityGifts());
                    }
                } else {
                    if (activity.getOrderType().intValue() == order.getOrderType() && order.getCommodityNum() >=
                            activity.getNum()) {
                        orderActivityGiftList.addAll(activity.getActivityGifts());
                    }
                }
            }
        }
        
        activities = iActivityService.findByActivityTypeAndStatusAndStartTimeBeforeAndEndTimeAfter(
                ActivityType.单一订单中商品总价.getValue(), ActivityStatus.发布.getValue(), modifyDate, modifyDate);
        if (CollectionUtils.isNotEmpty(activities)) {
            for (Activity activity : activities) {
                Integer endPrice = activity.getEndAmount() == null ? Integer.MAX_VALUE : activity.getEndAmount();
                if (activity.getOrderType().intValue() == -1) {
                    if (order.getRealPrice() >= activity.getStartAmount() && order.getRealPrice() < endPrice) {
                        orderActivityGiftList.addAll(activity.getActivityGifts());
                    }
                } else {
                    if (activity.getOrderType().intValue() == order.getOrderType()
                            && (order.getRealPrice() >= activity.getStartAmount() && order.getRealPrice() < endPrice)) {
                        orderActivityGiftList.addAll(activity.getActivityGifts());
                        break;
                    }
                }
            }
        }
        buildGiftsCommodityInfo(orderActivityGiftList);
        order.setActivityGifts(orderActivityGiftList);
    }
    
    private void getChannelActivityGifts(
            OrderContent orderContent, CommodityChannel commodityChannel, List<ActivityGift> activityGifts,
            Activity activity) throws CloneNotSupportedException {
        if (activity.getActivityType().intValue() == ActivityType.单一商品数量.getValue() && orderContent.getNum() >=
                activity.getNum()) {
            activityGifts.addAll(activity.getActivityGifts());
        } else if (activity.getActivityType().intValue() == ActivityType.单一商品总价.getValue() &&
                (CalcUtil.mul(orderContent.getNum(),
                        commodityChannel.getCommodityChannelPrise())) >= activity.getStartAmount()) {
            activityGifts.addAll(activity.getActivityGifts());
        } else if (activity.getActivityType().intValue() == ActivityType.单一商品数量累计_每满赠.getValue()) {
            int giftTimes = new BigDecimal(
                    Math.floor(orderContent.getNum() / activity.getNum())).intValue();
            List<ActivityGift> gifts = activity.getActivityGifts();
            if (giftTimes > 0 && CollectionUtils.isNotEmpty(gifts)) {
                for (ActivityGift gift : gifts) {
                    ActivityGift realGift = gift.clone();
                    realGift.setNum(giftTimes * gift.getNum());
                    activityGifts.add(realGift);
                }
            }
        } else if (activity.getActivityType().intValue() == ActivityType.单一商品总价累计_每满赠.getValue()) {
            int giftTimes = new BigDecimal(
                    Math.floor((CalcUtil.mul(orderContent.getNum(),
                            commodityChannel.getCommodityChannelPrise())) / activity.getStartAmount())).intValue();
            List<ActivityGift> gifts = activity.getActivityGifts();
            if (giftTimes > 0 && CollectionUtils.isNotEmpty(gifts)) {
                for (ActivityGift gift : gifts) {
                    ActivityGift realGift = gift.clone();
                    realGift.setNum(giftTimes * gift.getNum());
                    activityGifts.add(realGift);
                }
            }
        }
        buildGiftsCommodityInfo(activityGifts);
        orderContent.setActivityGifts(activityGifts);
    }
    
    private void buildGiftsCommodityInfo(List<ActivityGift> activityGifts) {
        if (CollectionUtils.isNotEmpty(activityGifts)) {
            for (ActivityGift activityGift : activityGifts) {
                //活动赠品改为终端商品
                CommodityTerminal commodityTerminal = iCommodityTerminalService.findOne(
                        activityGift.getCommodityTerminalID());
                Commodity commodity = iCommodityService.findOne(commodityTerminal.getCommodityID());
                activityGift.setCommodity(commodity);
            }
        }
    }
    
    /**
     * 获取客户订单，包括客户自己下单及销售代为下单的所有订单
     * <ul>
     * <li> </li>
     * </ul>
     *
     * @param customerUserID
     */
    @Override
    public ReturnBean<PageWrapper<Order>> getCustomerOrder(String customerUserID, Integer pageNum, Integer pageSize) {
        Condition condition = new Condition();
        List<FilterCondition> filterConditions = new ArrayList<FilterCondition>();
        filterConditions.add(new FilterCondition(customerUserID, "customerUserID", ConditionRelate.and.name(),
                Operation.eq.name(), 1));
        condition.setFilterCondition(filterConditions);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), Order.class).getResult();
        
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.DESC, "orderCommitTime"));
        Page<Order> page = findAll(condition.getSpecification(), pageable);
        List<Order> orderList = page.getContent();
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                getOrderInfo(order);
            }
        }
        return new ReturnBean<PageWrapper<Order>>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    private void buildCommodityInfo(Order order) {
        List<OrderContent> contentList = order.getOrderContents();
        if (CollectionUtils.isNotEmpty(contentList)) {
            for (OrderContent orderContent : contentList) {
                getCommodityByChannel(orderContent);
            }
        }
    }
    
    private void getCommodityByChannel(OrderContent orderContent) {
        String commodityChannelID = orderContent.getCommodityChannelID();
        CommodityChannel commodityChannel = iCommodityChannelService.findOne(commodityChannelID);
        if (commodityChannel != null) {
            ReturnBean<Commodity> commodityReturnBean = iCommodityService.getCommodityChannelByID(
                    commodityChannel.getCommodityID());
            if (commodityReturnBean.getCode() == 0) {
                orderContent.setCommodity(commodityReturnBean.getResult());
            }
        } else {
            logger.info("商品渠道ID为空，不能查询到对应的商品详情");
        }
    }
    
    @Override
    public ReturnBean<Order> getOrder(String orderID) {
        Order order = findOne(orderID);
        if (order == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        
        getOrderInfoWithGifst(order);
        
        return new ReturnBean<Order>(ResultCode.SUCCESS, "查询成功", order);
    }
    
    private Order getOrderInfo(Order order) {
        
        translateOrderInfo(order);
        
        buildCommodityInfo(order);
        
        OrderReceivingAddr orderReceivingAddr = iOrderReceivingAddrService.findByOrderID(order.getOrderID());
        order.setOrderReceivingAddr(orderReceivingAddr);
        
        Integer goodTransportType = order.getGoodTransportType();
        if (null != goodTransportType) {
            if (GoodTransportType.送货上门.getValue().intValue() == goodTransportType) {
                ReceivingAddr addr = iReceivingAddrService.findOne(orderReceivingAddr.getReceivingAddrID());
                order.setAddrStr(null != addr ? addr.getReceivingAddr() : "");
            }
            TakeGoodsShopInfo takeGoodsShopInfo = iTakeGoodsShopInfoService.findByOrderID(order.getOrderID());
            if (null != takeGoodsShopInfo) {
                Organization organization = iOrganizationService.findOne(takeGoodsShopInfo.getShopOrgID());
                takeGoodsShopInfo.setOrganization(organization);
                //order.setAddrStr(null != organization ? organization.getAddr() : "");
                order.setTakeGoodsShopInfo(takeGoodsShopInfo);
            }
        }
        
        PayInfo payInfo = iPayInfoService.findByOrderIDOrderByPayTimeDesc(order.getOrderID());
        order.setPayInfo(payInfo);
        
        if (null != order.getPayDeadline()) {
            //设置订单的剩余支付时间
            long payRestTime = order.getPayDeadline() - System.currentTimeMillis();
            order.setPayRestTime(payRestTime > 0 ? payRestTime : 0);
        }
        
        Introducer introducer = iIntroducerService.findByOrderID(order.getOrderID());
        order.setIntroducer(introducer);
        
        List<PayInfoPic> payInfoPics = iPayInfoPicService.findByOrderID(order.getOrderID());
        order.setPayInfoPics(payInfoPics);
        return order;
    }
    
    private Order getOrderInfoWithGifst(Order order) {
        
        this.getOrderInfo(order);
        
        List<Gift> gifts = order.getGifts();
        if (CollectionUtils.isNotEmpty(gifts)) {
            for (Gift gift : gifts) {
                Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                        gift.getCommodityTerminalID());
                gift.setCommodity(commodity);
            }
        }
        
        List<OrderContent> orderContents = order.getOrderContents();
        for (OrderContent orderContent : orderContents) {
            //设置终端信息
            CommodityTerminal cTerminal = iCommodityTerminalService.findOne(orderContent.getCommodityTerminalID());
            orderContent.setCommodityTerminal(cTerminal);
            //处理商品的赠品信息
            List<Gift> gifts1 = orderContent.getGifts();
            if (CollectionUtils.isNotEmpty(gifts1)) {
                for (Gift gift : gifts1) {
                    Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                            gift.getCommodityTerminalID());
                    gift.setCommodity(commodity);
                }
            }
        }
        return order;
    }
    
    /**
     * 对order的数据字典进行转换
     *
     * @param order
     */
    private void translateOrderInfo(Order order) {
        order.setStatusStr(OrderStatus.getName(order.getStatus()));
        order.setOrderTypeStr(OrderType.getName(order.getOrderType()));
        //客户姓名
        if (!StringUtils.isEmpty(order.getCustomerUserID())) {
            Customer customer = iCustomerService.findOne(order.getCustomerUserID());
            if (null != customer) {
                order.setCustomerUserName(customer.getCustomerName());
            } else {
                User customerUser = iUserService.findOne(order.getCustomerUserID());
                order.setCustomerUserName(null != customerUser ? customerUser.getName() : "");
            }
            
        }
        // 下单人
        if (!StringUtils.isEmpty(order.getBuyer())) {
            User buyer = iUserService.findOne(order.getBuyer());
            order.setBuyerName(null != buyer ? buyer.getName() : "");
        }
        if (null != order.getStatus()) {
            order.setStatusStr(OrderStatus.getName(order.getStatus()));
        }
    }
    
    @Override
    public ReturnBean<PageWrapper<Order>> getSalerOrder(
            String salerID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize) {
        if (iUserService.findOne(salerID) == null) {
            return new ReturnBean<PageWrapper<Order>>(ResultCode.ERROR_SERVICE, "销售员ID不正确");
        }
        
        Condition condition = new Condition();
        List<FilterCondition> filterConditions = new ArrayList<>();
        
        //判断customerID 是否是该销售员的客户
        //查询销售员的客户信息
        ReturnBean<PageWrapper<Order>> res = buildSalesFilterConditions(salerID, customerName, filterConditions);
        if (res != null) {
            return res;
        }
        
        if (!StringUtils.isEmpty(orderNo)) {
            filterConditions.add(
                    new FilterCondition(orderNo, "orderNo", ConditionRelate.and.name(), Operation.like.name(), 2));
        }
        if (orderType != null && orderType != -1) {
            filterConditions.add(new FilterCondition(String.valueOf(orderType), "orderType", ConditionRelate.and.name(),
                    Operation.eq.name(), 2));
        }
        if (status != null) {
            if (status.intValue() == 9) {
                filterConditions.add(new FilterCondition(OrderStatus.订单取消1109.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.订单取消1409.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.订单取消1509.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
            } else {
                filterConditions.add(new FilterCondition(String.valueOf(status), "status", ConditionRelate.and.name(),
                        Operation.eq.name(), 3));
            }
        }
        filterConditions.add(new FilterCondition(salerID, "salerID", ConditionRelate.and.name(),
                Operation.eq.name(), 1));
        condition.setFilterCondition(filterConditions);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), Order.class).getResult();
        
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.DESC, "orderCommitTime"));
        Page<Order> page = findAll(condition.getSpecification(), pageable);
        List<Order> orderList = page.getContent();
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                getOrderInfo(order);
            }
        }
        
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    @Override
    public ReturnBean<PageWrapper<Order>> getOrderByCnd(
            String orderNo, Integer orderType, String customerName, Integer status, Long startTime, Long endTime,
            Integer pageNum, Integer pageSize) {
        Condition condition = new Condition();
        List<FilterCondition> filterConditions = new ArrayList<FilterCondition>();
        if (!StringUtils.isEmpty(customerName)) {
            if (customerName.length() == 32 && !GeneralHelper.isChinese(customerName)) {
                filterConditions.add(new FilterCondition(customerName, "customerUserID", ConditionRelate.and.name(),
                        Operation.eq.name(), 1));
            } else {
                List<User> users = null;
                if (GeneralHelper.isChinese(customerName)) {
                    users = iUserService.findByNameLike("%" + customerName + "%");
                } else {
                    users = iUserService.findByNamePinYinLike(customerName + "%");
                }
                if (CollectionUtils.isEmpty(users)) {
                    Page page = new PageImpl(new ArrayList());
                    return new ReturnBean<PageWrapper<Order>>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
                }
                List<String> customerIDs = new ArrayList<>();
                for (User user : users) {
                    customerIDs.add(user.getUserID());
                }
                filterConditions.add(new FilterCondition(customerIDs, "customerUserID", ConditionRelate.and.name(),
                        Operation.in.name(), 1));
            }
        }
        if (!StringUtils.isEmpty(orderNo)) {
            filterConditions.add(
                    new FilterCondition(orderNo, "orderNo", ConditionRelate.and.name(), Operation.like.name(), 2));
        }
        if (orderType != null && orderType != -1) {
            filterConditions.add(new FilterCondition(String.valueOf(orderType), "orderType", ConditionRelate.and.name(),
                    Operation.eq.name(), 2));
        }
        if (status != null) {
            if (status.intValue() == 9) {
                filterConditions.add(new FilterCondition("1109", "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition("1409", "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition("1509", "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
            } else {
                filterConditions.add(new FilterCondition(String.valueOf(status), "status", ConditionRelate.and.name(),
                        Operation.eq.name(), 3));
            }
        }
        
        if (null != startTime) {
            filterConditions.add(new FilterCondition(String.valueOf(startTime), "returnSalesTime",
                    ConditionRelate.and.name(), Operation.ge.name(), 5));
        }
        if (null != endTime) {
            filterConditions.add(new FilterCondition(String.valueOf(endTime), "returnSalesTime",
                    ConditionRelate.and.name(), Operation.lt.name(), 6));
        }
        
        condition.setFilterCondition(filterConditions);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), Order.class).getResult();
        
        Sort sort = new Sort(Sort.Direction.DESC, "orderNo");
        sort = sort.and(new Sort(Sort.Direction.DESC, "orderCommitTime"));
        
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, sort);
        Page<Order> page = findAll(condition.getSpecification(), pageable);
        
        List<Order> orderList = page.getContent();
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                getOrderInfo(order);
            }
        }
        
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    @Override
    public ReturnBean<Order> getOrder(String orderID, Integer payType) {
        return null;
    }
    
    //@Override
    public ReturnBean<String> payLocal(
            String orderID, Integer payType, Integer clientType,
            BigDecimal amount) throws IOException, AlipayApiException {
        ReturnBean<String> returnBean;
        Order order = findOne(orderID);
        if (order == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        //  订单金额
        BigDecimal sum = new BigDecimal(String.valueOf(order.getRealPrice())).setScale(2, BigDecimal.ROUND_DOWN);
        
        String htmlCode = null;
        if (PayType.支付宝.getValue().intValue() == payType || PayType.微信支付.getValue().intValue() == payType) {
            ReturnBean<String> aliResult = payService.doPay(orderID, order.getOrderNo(), "", payType, clientType,
                    String.valueOf(sum));
            if (aliResult.getCode().intValue() == ResultCode.SUCCESS.intValue()) {
                htmlCode = aliResult.getResult();
            } else {
                return new ReturnBean<>(aliResult.getCode(), aliResult.getMsg(), htmlCode);
            }
        } else {
            //生成支付信息
            PayInfo payInfo = new PayInfo();
            payInfo.setPayInfoID(Identities.uuid2());
            payInfo.setOrderID(orderID);
            //默认设置为订单的应付款金额，后续不同的支付方式，再根据前端传入的参数进行设置
            payInfo.setAmount(order.getRealPrice());
            payInfo.setPayAccount(null);
            payInfo.setPayTime(System.currentTimeMillis());
            payInfo.setPayType(payType);
            
            //启动工作流， 根据不同的订单类型
            //Integer targetStatus = OrderUtil.getOnlinePayCurrStatus4Workflow(order, true);
            Integer currStatus = null;
            if (PayType.现金.getValue().intValue() == payType) {
                currStatus = OrderStatus.订单己支付.getValue();
            } else if (PayType.货到付款.getValue().intValue() == payType) {
                currStatus = OrderStatus.货到付款_未支付.getValue();
            } else if (PayType.白条支付.getValue().intValue() == payType) {
                currStatus = OrderStatus.白条已支付.getValue();
                payInfo.setAmount(0.0);
            } else if (PayType.支付定金.getValue().intValue() == payType) {
                currStatus = OrderStatus.支付定金.getValue();
                payInfo.setAmount(amount.multiply(new BigDecimal("100")).doubleValue());
            }
            order.setStatus(currStatus);
            
            order.setPayTime(System.currentTimeMillis());
            save(order);
            // 货到付款的方式也会向PayInfo 表写记录， 单独再提供一个接口给工作流调用，再插入真正的付款信息，付款方式为现金支付
            iPayInfoService.save(payInfo);
            
            if (OrderType.宴会订单.getValue().intValue() == order.getOrderType()) {
                decreaseStockForBanquetOrder(order);
            }
            
            /*if (PayType.现金.getValue().intValue() == payType || PayType.货到付款.getValue().intValue() == payType
                    || PayType.白条支付.getValue().intValue() == payType || PayType.支付定金.getValue().intValue() == payType) {
                iOrderFlowService.startWorkflow(order.getBuyer(), orderID, currStatus.toString(), null);
            }*/
            startWorkFlow(orderID, payType, order);
            
        }
        
        return new ReturnBean<>(0, "支付完成", htmlCode);
    }
    
    @Override
    public ReturnBean<String> pay(
            String orderID, Integer payType, Integer clientType,
            BigDecimal amount) throws IOException, AlipayApiException {
        ReturnBean<String> returnBean;
        Order order = findOne(orderID);
        if (order == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        //  订单金额
        BigDecimal sum = new BigDecimal(String.valueOf(order.getRealPrice())).setScale(2, BigDecimal.ROUND_DOWN);
        
        String htmlCode = null;
        if (PayType.支付宝.getValue().intValue() == payType || PayType.微信支付.getValue().intValue() == payType) {
            ReturnBean<String> aliResult = payService.doPay(orderID, order.getOrderNo(), "", payType, clientType,
                    String.valueOf(sum));
            if (aliResult.getCode().intValue() == ResultCode.SUCCESS.intValue()) {
                htmlCode = aliResult.getResult();
            } else {
                return new ReturnBean<>(aliResult.getCode(), aliResult.getMsg(), htmlCode);
            }
        } else {
            //生成支付信息
            PayInfo payInfo = new PayInfo();
            payInfo.setPayInfoID(Identities.uuid2());
            payInfo.setOrderID(orderID);
            //默认设置为订单的应付款金额，后续不同的支付方式，再根据前端传入的参数进行设置
            payInfo.setAmount(order.getRealPrice());
            payInfo.setPayAccount(null);
            payInfo.setPayTime(System.currentTimeMillis());
            payInfo.setPayType(payType);
            
            //启动工作流， 根据不同的订单类型
            //Integer targetStatus = OrderUtil.getOnlinePayCurrStatus4Workflow(order, true);
            Integer currStatus = null;
            if (PayType.现金.getValue().intValue() == payType) {
                currStatus = OrderStatus.订单己支付.getValue();
            } else if (PayType.货到付款.getValue().intValue() == payType) {
                currStatus = OrderStatus.货到付款_未支付.getValue();
            } else if (PayType.白条支付.getValue().intValue() == payType) {
                currStatus = OrderStatus.白条已支付.getValue();
                payInfo.setAmount(0.0);
            } else if (PayType.支付定金.getValue().intValue() == payType) {
                currStatus = OrderStatus.支付定金.getValue();
                payInfo.setAmount(amount.multiply(new BigDecimal("100")).doubleValue());
            }
            order.setStatus(currStatus);
            
            order.setPayTime(System.currentTimeMillis());
            save(order);
            // 货到付款的方式也会向PayInfo 表写记录， 单独再提供一个接口给工作流调用，再插入真正的付款信息，付款方式为现金支付
            iPayInfoService.save(payInfo);
            
            if (OrderType.宴会订单.getValue().intValue() == order.getOrderType()) {
                decreaseStockForBanquetOrder(order);
            }
            
            /*if (PayType.现金.getValue().intValue() == payType || PayType.货到付款.getValue().intValue() == payType
                    || PayType.白条支付.getValue().intValue() == payType || PayType.支付定金.getValue().intValue() == payType) {
                iOrderFlowService.startWorkflow(order.getBuyer(), orderID, currStatus.toString(), null);
            }*/
            startWorkFlow(orderID, payType, order);
            
        }
        
        return new ReturnBean<>(0, "支付完成", htmlCode);
    }
    
    private void startWorkFlow(String orderID, Integer payType, Order order) {
        //启动工作流， 根据不同的订单类型
        if (OrderType.会员订单.getValue().intValue() == order.getOrderType().intValue()
                && (PayType.现金.getValue().intValue() == payType || PayType.货到付款.getValue().intValue() == payType)) {
            //销售	客户	现金支付（包括扫码及现金）
            iOrderFlowService.startWorkflow(order.getBuyer(), orderID, order.getStatus().toString(), null);
        } else if ((OrderType.流通订单.getValue().intValue() == order.getOrderType().intValue()
                || OrderType.酒店订单.getValue().intValue() == order.getOrderType().intValue())
                && (PayType.现金.getValue().intValue() == payType || PayType.货到付款.getValue().intValue() == payType
                || PayType.白条支付.getValue().intValue() == payType)) {
            iOrderFlowService.startWorkflow(order.getBuyer(), orderID, order.getStatus().toString(), null);
        } else if (OrderType.签单订单.getValue().intValue() == order.getOrderType().intValue()
                && PayType.白条支付.getValue().intValue() == payType) {
            iOrderFlowService.startWorkflow(order.getBuyer(), orderID, order.getStatus().toString(), null);
        } else if (OrderType.订货会酒店订单.getValue().intValue() == order.getOrderType().intValue()
                || OrderType.订货会流通订单.getValue().intValue() == order.getOrderType().intValue()
                || OrderType.酒店订单.getValue().intValue() == order.getOrderType().intValue()
                || OrderType.还货订单.getValue().intValue() == order.getOrderType().intValue()) {
            iOrderFlowService.startWorkflow(order.getBuyer(), orderID, order.getStatus().toString(), null);
        } else if (OrderType.无款订单.getValue().intValue() == order.getOrderType().intValue()) {
            iOrderFlowService.startWorkflow(order.getBuyer(), orderID, order.getStatus() + "", null);
        } else if (OrderType.宴会订单.getValue().intValue() == order.getOrderType().intValue()) {
            //宴会只有现款支付
            iOrderFlowService.startWorkflow(order.getBuyer(), orderID, order.getStatus() + "", null);
        }
    }
    
    @Override
    public ReturnBean<Order> getVerifyOrder(String userID, String order) throws CloneNotSupportedException {
        Order orderEntity = JSON.parseObject(order, Order.class);
        if (orderEntity == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单信息不能为空！");
        }
        
        return handleOrder(orderEntity);
    }
    
    @Override
    public void orderTimeoutRefresh() {
        //查询即将过期的订单信息， 不查询还货订单和内欠订单（创建订单时，换货订单和内欠订单没有写支付到期时间的值）
        //只查询自助下单的、到期未支付的、非内欠订单（内欠订单是店员下单，默认为自助下单）
        List<Order> orderList = findByPlaceOrderTypeAndStatusAndOrderTypeNotAndPayDeadlineLessThan(
                PlaceOrderType.自助下单.getValue(), OrderStatus.订单提交_未支付.getValue(), OrderType.无款订单.getValue(),
                System.currentTimeMillis());
        
        //将订单设置为为无效，同时恢复库存
        if (CollectionUtils.isEmpty(orderList)) {
            logger.info(">>> 没有找到需要刷新的未支付订单...");
            return;
        }
        
        //恢复库存有两种实现方式 ① 查询订单得到订单正品和赠品及订单的赠品进行累加，恢复库存 ② 是直接找到当时出库的出库流水信息，反向进行入库操作 ，此处采用第二种方式，比较方便
        Long modifyDate = System.currentTimeMillis();
        
        for (Order order : orderList) {
            //购买人
            //User buyer = iUserService.findOne(order.getBuyer());
            //购买人角色
            //List<Role> roles = iUserRoleService.findRolesByUserID(order.getBuyer());
            //Role role = roles.get(0);
            //得到仓库的ID，然后恢复库存
            //String warehouseID = this.getWarehouseID(order, buyer, role);
            
            try {
                cancelOrder(modifyDate, order, OrderStatus.订单取消1109.getValue());
            } catch (Exception e) {
                logger.error(">>>刷新未支付订单出错", e);
                //e.printStackTrace();
                continue;
            }
        }
    }
    
    @Override
    public ReturnBean<String> cancelOrder(String orderID, Integer orderStatus) {
        Order order = findOne(orderID);
        if (null == order) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确！");
        }
        if (order.getStatus().intValue() > OrderStatus.白条已支付.getValue()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "已完成支付的订单不能取消！");
        }
        cancelOrder(System.currentTimeMillis(), order, OrderStatus.订单取消1109.getValue());
        return new ReturnBean<>(ResultCode.SUCCESS.intValue(), "订单取消成功");
    }
    
    private void cancelOrder(Long modifyDate, Order order, Integer orderStatus) {
        if (orderStatus == null) {
            orderStatus = OrderStatus.订单取消1109.getValue();
        }
        OutStock outStock = iOutStockService.findByProofID(order.getOrderID());
        // 入库
        InStock inStock = new InStock();
        inStock.setInStockID(Identities.uuid2());
        inStock.setInStockType(InStockType.订单取消.getValue());
        inStock.setInStocker(order.getBuyer());
        inStock.setProofID(order.getOrderID());
        inStock.setWarehouseID(outStock.getWarehouseID());
        inStock.setModifyDate(modifyDate);
        List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
        
        if (null != outStock && CollectionUtils.isNotEmpty(outStock.getInOutStockDetails())) {
            for (InOutStockDetail inOutStockDetail : outStock.getInOutStockDetails()) {
                OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails,
                        inOutStockDetail.getCommodityTerminalID(),
                        inOutStockDetail.getNum());
            }
        }
        order.setStatus(orderStatus);
        save(order);
        inStock.setInOutStockDetails(inOutStockDetails);
        iStockService.addInStock(inStock);
    }
    
    @Override
    public List<Order> findByPayTimeIsNullAndPayDeadlineLessThan(Long payDeadline) {
        return saleOrderRepository.findByPayTimeIsNullAndPayDeadlineLessThan(payDeadline);
    }
    
    @Override
    public List<Order> findByPlaceOrderTypeAndStatusAndOrderTypeNotAndPayDeadlineLessThan(
            Integer placeOrderType, Integer status, Integer orderType, Long payDeadline) {
        return saleOrderRepository.findByPlaceOrderTypeAndStatusAndOrderTypeNotAndPayDeadlineLessThan(placeOrderType,
                status, orderType, payDeadline);
    }
    
    @Override
    public ReturnBean<List<net.wofly.sale.order.domain.OrderType>> getAllOrderTypes() {
        List<net.wofly.sale.order.domain.OrderType> orderTypes = iOrderTypeService.findByStatus(
                CommonStatus.有效.getValue());
        net.wofly.sale.order.domain.OrderType orderType = new net.wofly.sale.order.domain.OrderType();
        orderType.setOrderTypeID("-1");
        orderType.setOrderTypeName("所有订单");
        orderTypes.add(orderType);
        return new ReturnBean<>(ResultCode.SUCCESS, "获取订单类型成功", orderTypes);
    }
    
    @Override
    public ReturnBean<List<net.wofly.sale.order.domain.OrderType>> getOrderTypeByRole(String roleID) throws
            CloneNotSupportedException {
        List<net.wofly.sale.order.domain.OrderType> orderTypesReturn = new ArrayList<>();
        List<net.wofly.sale.order.domain.OrderType> orderTypes = iRoleOrderTypeService.findByRoleIDAndStatus(
                roleID, CommonStatus.有效.getValue());
        
        if (CollectionUtils.isNotEmpty(orderTypes)) {
            //查找角色的默认订单类型
            RoleDefaultOrderType roleDefaultOrderType = iRoleDefaultOrderTypeService.findByRoleID(roleID);
            for (net.wofly.sale.order.domain.OrderType orderType : orderTypes) {
                if (orderType.getOrderTypeID().equals(roleDefaultOrderType.getOrderType())) {
                    orderType.setIsDefault(1);
                }
                //根据角色获取订单类型接口返回结果中去除还货订单，还货订单又单独的下单入口
                if (!OrderType.还货订单.getValue().toString().equals(orderType.getOrderTypeID())) {
                    net.wofly.sale.order.domain.OrderType orderTypeClone = orderType.clone();
                    orderTypesReturn.add(orderTypeClone);
                }
            }
        }
        return new ReturnBean<>(ResultCode.SUCCESS, "根据角色获取订单类型成功", orderTypesReturn);
    }
    
    /**
     * 获取订单状态，订单查询页面搜索条件
     */
    @Override
    public ReturnBean<List<OrderStatusDto>> getOrderStatus() {
        OrderStatus[] values = OrderStatus.values();
        List<OrderStatusDto> orderStatuses = new ArrayList<>();
        
        for (OrderStatus value : values) {
            if (!value.getName().equals("订单取消") && !value.getName().equals("草稿")) {
                OrderStatusDto dto = new OrderStatusDto(value.getValue(), value.getName());
                orderStatuses.add(dto);
            }
        }
        OrderStatusDto dto = new OrderStatusDto(9, "订单取消");
        orderStatuses.add(dto);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "获取订单状态成功", orderStatuses);
    }
    
    /**
     * 更改订单类型
     *
     * @param orderType
     * @param order
     * @return
     */
    @Override
    public ReturnBean<Order> changeOrderType(Integer orderType, Order order) throws CloneNotSupportedException {
        order.setPlaceOrderType(PlaceOrderType.代客下单.getValue());
        order.setOrderType(orderType);
        
        for (OrderContent orderContent : order.getOrderContents()) {
            if (orderContent.getCommodity() == null || org.apache.commons.lang3.StringUtils.isBlank(
                    orderContent.getCommodity().getCommodityID())) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "商品ID不能为空！");
            }
            Commodity commodity = iCommodityService.findOne(orderContent.getCommodity().getCommodityID());
            if (commodity == null) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE,
                        "商品(" + orderContent.getCommodity().getCommodityID() + ")未找到！");
            }
            
            //查找订单类型和渠道的关系
            OrderTypeChannelMapping orderTypeChannelMapping = iOrderTypeChannelMappingService.findByOrderType(
                    String.valueOf(orderType));
            if (null == orderTypeChannelMapping) {
                logger.info(">>> 未找到订单类型和渠道的关系配置数据...");
            }
            
            //查找商品渠道
            CommodityChannel commodityChannel = iCommodityChannelService.findByCommodityIDAndChannel(
                    commodity.getCommodityID(), orderTypeChannelMapping.getChannel());
            orderContent.getCommodity().setCommodityChannel(commodityChannel);
            
            //orderContent.setCommodity(commodity);
            orderContent.setCommodityChannelID(commodityChannel.getCommodityChannelID());
        }
        
        ReturnBean<Order> returnBean = this.handleOrder(order);
        if (ResultCode.SUCCESS.intValue() == returnBean.getCode().intValue()) {
            return new ReturnBean<>(ResultCode.SUCCESS, "更改订单类型成功", returnBean.getResult());
        } else {
            return new ReturnBean<>(returnBean.getCode(), returnBean.getMsg(), returnBean.getResult());
        }
    }
    
    /**
     * 重新写入订单的真正支付信息，向payInfo表插入记录
     *
     * @param orderID
     * @return
     */
    @Override
    public ReturnBean<String> reWritePayInfo4WorkFlowConfirmReceiveable(String orderID) {
        Order order = findOne(orderID);
        if (order == null) {
            return new ReturnBean<String>(ResultCode.ERROR_SERVICE, "orderID不正确");
        }
        //生成支付信息
        PayInfo payInfo = new PayInfo();
        payInfo.setPayInfoID(Identities.uuid2());
        payInfo.setOrderID(orderID);
        //默认设置为订单的应付款金额
        payInfo.setAmount(order.getRealPrice());
        payInfo.setPayAccount(null);
        payInfo.setPayTime(System.currentTimeMillis());
        payInfo.setPayType(PayType.现金.getValue());
        iPayInfoService.save(payInfo);
        
        //更新订单的支付时间
        order.setPayTime(System.currentTimeMillis());
        save(order);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "重写订单支付信息成功");
    }
    
    /**
     * 获取客户的还货商品库存
     *
     * @param customerUserID
     * @return
     */
    @Override
    public ReturnBean<List<ReturnGoodsDtoResp>> getCustomerReturnGoodsStock(
            String customerUserID) {
        List<Stock> stockList = iStockService.findByWarehouseIDAndNumGreaterThan(customerUserID, 0);
        if (!CollectionUtils.isEmpty(stockList)) {
            List<ReturnGoodsDtoResp> respList = new ArrayList<>();
            for (Stock stock : stockList) {
                Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                        stock.getCommodityTerminalID());
                ReturnGoodsDtoResp respDto = new ReturnGoodsDtoResp();
                respDto.setCommodityTmlID(stock.getCommodityTerminalID());
                respDto.setRestNum(stock.getNum());
                respDto.setCommodity(commodity);
                respList.add(respDto);
            }
            return new ReturnBean<>(ResultCode.SUCCESS, "获取客户的还货商品库存成功", respList);
        }
        return new ReturnBean<>(ResultCode.SUCCESS, "获取客户的还货商品库存成功");
    }
    
    /**
     * 创建订单（还货订单专用）
     *
     * @param returnGoodsOrderReq
     * @return
     */
    @Override
    public ReturnBean<Order> createOrderForReturnGoods(ReturnGoodsOrderReq returnGoodsOrderReq) {
        Long modifyDate = System.currentTimeMillis();
        //下单人
        User buyer = iUserService.findOne(returnGoodsOrderReq.getBuyerID());
        if (null == buyer) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单人信息不正确");
        }
        String orderID = Identities.uuid2();
        
        String customerUserID = returnGoodsOrderReq.getCustomerUserID();
        List<Role> roles = iUserRoleService.findRolesByUserID(customerUserID);
        if (CollectionUtils.isEmpty(roles)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "客户没有分配角色，请先给客户分配角色");
        }
        Integer channel = null;
        if (roles.get(0).getRoleID().equals(RoleEnum.流通客户.getValue())) {
            channel = Channel.流通.getValue();
        } else if (roles.get(0).getRoleID().equals(RoleEnum.酒店客户.getValue())) {
            channel = Channel.酒店.getValue();
        }
        
        List<ReceivingAddr> receivingAddrList = iReceivingAddrService
                .findByUserIDAndStatusOrderByDefaultFlagDesc(customerUserID, CommonStatus.有效.getValue());
        if (CollectionUtils.isEmpty(receivingAddrList)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未查询到客户的默认收货地址信息，请先维护客户收货地址");
        }
        //选取客户的默认收货地址
        OrderReceivingAddr addr = new OrderReceivingAddr();
        addr.setOrderReceivingAddrID(Identities.uuid2());
        addr.setOrderID(orderID);
        addr.setReceivingAddrID(receivingAddrList.get(0).getReceivingAddrID());
        addr.setModifyDate(modifyDate);
        iOrderReceivingAddrService.save(addr);
        
        Order order = new Order();
        order.setOrderID(orderID);
        order.setPlaceOrderType(PlaceOrderType.代客下单.getValue());
        order.setBuyer(returnGoodsOrderReq.getBuyerID());
        order.setSalerID(returnGoodsOrderReq.getBuyerID());
        order.setCustomerUserID(customerUserID);
        order.setOrderType(OrderType.还货订单.getValue());
        order.setStatus(OrderStatus.订单己支付.getValue());
        order.setGoodTransportType(GoodTransportType.送货上门.getValue());
        
        TakeGoodsShopInfo takeGoodsShopInfo = new TakeGoodsShopInfo();
        takeGoodsShopInfo.setOrderID(orderID);
        takeGoodsShopInfo.setTakeGoodsShopInfoID(Identities.uuid2());
        //销售的所属门店
        takeGoodsShopInfo.setShopOrgID(buyer.getOrganizationID());
        takeGoodsShopInfo.setModifyDate(modifyDate);
        iTakeGoodsShopInfoService.save(takeGoodsShopInfo);
        
        List<OrderContent> orderContents = new ArrayList<>();
        //销售出库
        OutStock outStock1 = new OutStock();
        outStock1.setOutStockType(OutStockType.订单出库.getValue());
        outStock1.setProofID(orderID);
        outStock1.setOutStocker(order.getBuyer());
        outStock1.setModifyDate(modifyDate);
        outStock1.setWarehouseID(order.getBuyer());
        
        //客户出库
        OutStock outStock2 = new OutStock();
        outStock2.setOutStockType(OutStockType.订单出库.getValue());
        outStock2.setProofID(orderID);
        outStock2.setOutStocker(order.getBuyer());
        outStock2.setModifyDate(modifyDate);
        outStock2.setCustomerOutStock(true);
        outStock2.setWarehouseID(customerUserID);
        
        int totalCommodityNum = 0;
        
        List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
        for (CommodityTmlDto tmlDto : returnGoodsOrderReq.getReturnCommodityTmlDtos()) {
            Commodity commodity = iCommodityTmlService.findCommodityByCommodityTerminalID(
                    tmlDto.getCommodityTmlID());
            CommodityChannel commodityChannel = iCommodityChannelService.findByCommodityIDAndChannel(
                    commodity.getCommodityID(), String.valueOf(channel));
            totalCommodityNum += tmlDto.getNum();
            //先查询客户的库存
            Stock customerStock = iStockService.findByWarehouseIDAndCommodityTerminalID(customerUserID,
                    tmlDto.getCommodityTmlID());
            if (null == customerStock) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未查询到客户相对的商品库存信息，请检查");
            }
            if (customerStock.getNum() < tmlDto.getNum()) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "还货商品数量超过客户的库存数据，请检查");
            }
            
            //再查询销售的库存
            if (orderConfig.isCheckStock()) {
                Stock stock = iStockService.findByWarehouseIDAndCommodityTerminalID(buyer.getWarehouseID(),
                        tmlDto.getCommodityTmlID());
                if (null == stock) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未查询到业务员（销售）相对的商品库存信息，请检查");
                }
                if (stock.getNum() < tmlDto.getNum()) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "还货商品数量超过业务员（销售）的库存数据，请检查");
                }
            }
            
            OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails, tmlDto.getCommodityTmlID(),
                    tmlDto.getNum());
            
            OrderContent content = new OrderContent();
            content.setOrderContentID(Identities.uuid2());
            content.setOrderID(orderID);
            content.setNum(tmlDto.getNum());
            content.setPreorderNum(content.getNum());
            content.setCommodityChannelID(commodityChannel.getCommodityChannelID());
            content.setCommodityTerminalID(tmlDto.getCommodityTmlID());
            content.setPrice(commodityChannel.getCommodityChannelPrise());
            content.setTotalPrice(commodityChannel.getCommodityChannelPrise() * content.getNum());
            content.setModifyDate(modifyDate);
            orderContents.add(content);
        }
        order.setOrderContents(orderContents);
        
        order.setCommodityNum(totalCommodityNum);
        order.setCommodityTotalNum(totalCommodityNum);
        order.setAmount(0.0);
        order.setRealPrice(0.0);
        order.setActivityAmount(0.0);
        
        //生成订单编号
        String orderNO = generateOrderNO();
        order.setOrderNo(orderNO);
        order.setOrderCommitTime(modifyDate);
        order = save(order);
        
        outStock1.setInOutStockDetails(inOutStockDetails);
        iStockService.addOutStock(outStock1);
        
        outStock2.setInOutStockDetails(inOutStockDetails);
        iStockService.addOutStock(outStock2);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "创建订单（还货订单专用）成功", order);
    }
    
    /**
     * 创建订单（无款订单专用），只是为了销库存
     *
     * @param noMoneyOrderReq
     * @return
     */
    @Override
    public ReturnBean<Order> createNoMoneyOrder(NoMoneyOrderReq noMoneyOrderReq) {
        //下单人
        User buyer = iUserService.findOne(noMoneyOrderReq.getBuyerID());
        if (null == buyer) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单人信息不正确");
        }
        Long modifyDate = System.currentTimeMillis();
        //将收货客户设置为自己
        noMoneyOrderReq.setCustomerUserID(noMoneyOrderReq.getBuyerID());
        String orderID = Identities.uuid2();
        ReturnBean<Order> canNotCreateOrder = checkUserHasCreateOrderPermission(noMoneyOrderReq.getBuyerID());
        if (canNotCreateOrder != null) {
            return canNotCreateOrder;
        }
        
        Order order = new Order();
        order.setOrderID(orderID);
        order.setPlaceOrderType(PlaceOrderType.自助下单.getValue());
        order.setBuyer(noMoneyOrderReq.getBuyerID());
        order.setSalerID(noMoneyOrderReq.getBuyerID());
        order.setCustomerUserID(noMoneyOrderReq.getCustomerUserID());
        order.setOrderType(OrderType.无款订单.getValue());
        order.setStatus(OrderStatus.草稿.getValue());
        //order.setGoodTransportType(GoodTransportType.门店自取.getValue());
        order.setDescp(noMoneyOrderReq.getDescp());
        order.setOrderCommitTime(modifyDate);
        
        int totalCommodityNum = 0;
        Integer realPrice = 0;
        
        List<OrderContent> orderContents = new ArrayList<>();
        for (CommodityTmlDto tmlDto : noMoneyOrderReq.getCommodityTmlDtos()) {
            CommodityTerminal terminal = iCommodityTmlService.findOne(tmlDto.getCommodityTmlID());
            if (null == terminal) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单商品终端ID不正确");
            }
            
            List<ChannelCommodityTerminalMapping> mappings = iChannelCommodityTmlMappingService
                    .findByCommodityTerminalType(terminal.getCommodityTerminalType());
            if (CollectionUtils.isEmpty(mappings)) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未查询到改终端商品对应的渠道信息");
            }
            String channel = mappings.get(0).getChannel();
            
            CommodityChannel commodityChannel = iCommodityChannelService.findByCommodityIDAndChannel(
                    terminal.getCommodityID(), channel);
            
            OrderContent content = new OrderContent();
            content.setOrderContentID(Identities.uuid2());
            content.setOrderID(orderID);
            content.setNum(tmlDto.getNum());
            totalCommodityNum += content.getNum();
            content.setPreorderNum(content.getNum());
            content.setCommodityChannelID(commodityChannel.getCommodityChannelID());
            content.setCommodityTerminalID(tmlDto.getCommodityTmlID());
            content.setPrice(commodityChannel.getCommodityChannelPrise());
            content.setTotalPrice(CalcUtil.mul(commodityChannel.getCommodityChannelPrise(), content.getNum()));
            content.setModifyDate(modifyDate);
            orderContents.add(content);
        }
        order.setOrderContents(orderContents);
        
        order.setRealPrice(0.0);
        order.setActivityAmount(0.0);
        order.setAmount(0.0);
        
        order.setCommodityNum(totalCommodityNum);
        order.setCommodityTotalNum(totalCommodityNum);
        
        //生成订单编号
        String orderNO = generateOrderNO();
        order.setOrderNo(orderNO);
        
        order = save(order);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "创建订单（无款订单）成功", order);
    }
    
    /**
     * 修改订单（无款订单专用），只是为了销库存
     *
     * @param order
     * @return
     */
    @Override
    public ReturnBean<Order> updateNoMoneyOrder(Order order) {
        Order dbOrder = findOne(order.getOrderID());
        if (null == dbOrder) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        
        if (OrderType.无款订单.getValue().intValue() != order.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非无款订单不可以修改订单");
        }
        
        //下单人校验
        if (!dbOrder.getBuyer().equals(order.getBuyer())) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单人信息不正确,不可以修改订单");
        }
        
        ReturnBean<Order> canNotCreateOrder = checkUserHasCreateOrderPermission(order.getBuyer());
        if (canNotCreateOrder != null) {
            return canNotCreateOrder;
        }
        
        Long modifyDate = System.currentTimeMillis();
        int totalCommodityNum = 0;
        
        order.setSalerID(dbOrder.getSalerID());
        order.setOrderType(OrderType.无款订单.getValue());
        order.setStatus(OrderStatus.草稿.getValue());
        
        for (OrderContent content : order.getOrderContents()) {
            CommodityTerminal terminal = iCommodityTmlService.findOne(content.getCommodityTerminalID());
            if (null == terminal) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单商品终端ID不正确");
            }
            
            List<ChannelCommodityTerminalMapping> mappings = iChannelCommodityTmlMappingService
                    .findByCommodityTerminalType(terminal.getCommodityTerminalType());
            if (CollectionUtils.isEmpty(mappings)) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未查询到改终端商品对应的渠道信息");
            }
            String channel = mappings.get(0).getChannel();
            
            CommodityChannel commodityChannel = iCommodityChannelService.findByCommodityIDAndChannel(
                    terminal.getCommodityID(), channel);
            
            if (StringUtils.isEmpty(content.getOrderContentID())) {
                content.setOrderContentID(Identities.uuid2());
            }
            content.setOrderID(order.getOrderID());
            content.setPreorderNum(content.getNum());
            totalCommodityNum += content.getNum();
            content.setCommodityChannelID(commodityChannel.getCommodityChannelID());
            content.setPrice(commodityChannel.getCommodityChannelPrise());
            content.setTotalPrice(CalcUtil.mul(commodityChannel.getCommodityChannelPrise(), content.getNum()));
            content.setModifyDate(modifyDate);
        }
        
        order.setRealPrice(0.0);
        order.setActivityAmount(0.0);
        order.setAmount(0.0);
        
        order.setCommodityNum(totalCommodityNum);
        order.setCommodityTotalNum(totalCommodityNum);
        
        order.setOrderNo(dbOrder.getOrderNo());
        order.setOrderCommitTime(modifyDate);
        iSaleOrderContentService.deleteByOrderID(order.getOrderID());
        order = save(order);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "修改订单（无款订单）成功", order);
    }
    
    /**
     * 删除订单（无款订单专用）
     *
     * @param orderID
     * @return
     */
    @Override
    public ReturnBean<String> deleteNoMoneyOrder(String orderID) {
        Order order = findOne(orderID);
        if (null == order) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        if (OrderType.无款订单.getValue().intValue() != order.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非无款订单不可以删除");
        }
        if (OrderStatus.草稿.getValue().intValue() != order.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非草稿状态的无款订单不可以删除");
        }
        
        iSaleOrderContentService.deleteByOrderID(orderID);
        delete(orderID);
        return new ReturnBean<>(ResultCode.SUCCESS, "删除成功");
    }
    
    /**
     * 创建宴会订单（宴会订单专用）
     *
     * @param banquetOrderReq
     * @return
     */
    @Override
    public ReturnBean<Order> createBanquetOrder(BanquetOrderReq banquetOrderReq) throws CloneNotSupportedException {
        //下单人
        User buyer = iUserService.findOne(banquetOrderReq.getBuyerID());
        if (null == buyer) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单人信息不正确");
        }
        
        Activity activity = iActivityService.findOne(banquetOrderReq.getActivityID());
        if (activity == null) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "活动ID（activityID）不正确");
        }
        
        if (ActivityType.单一商品数量累计_每满赠.getValue().intValue() != activity.getActivityType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "宴会活动ID不正确（单一商品数量累计_每满赠的活动才可以下单）");
        }
        
        if (OrderType.宴会订单.getValue().intValue() != activity.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "活动ID不正确（此活动不是宴会订单类的活动）");
        }
        
        Long modifyDate = System.currentTimeMillis();
        Order order = new Order();
        String orderID = Identities.uuid2();
        order.setOrderID(orderID);
        order.setOrderCommitTime(modifyDate);
        order.setBuyer(banquetOrderReq.getBuyerID());
        order.setSalerID(banquetOrderReq.getBuyerID());
        order.setCustomerUserID(banquetOrderReq.getCustomerUserID());
        
        order.setPlaceOrderType(PlaceOrderType.代客下单.getValue());
        order.setOrderType(OrderType.宴会订单.getValue());
        order.setStatus(OrderStatus.订单提交_未支付.getValue());
        order.setDescp(banquetOrderReq.getDescp());
        
        Map<String, Integer> stockMap = new HashMap<>();
        Map<String, String> terminalNameMap = new HashMap<>();
        Map<String, String> terminalMsgMap = new HashMap<>();
        
        int orderGiftNum = 0;
        int totalCommodityNum = 0;
        Double realPrice = 0.0;
        
        List<OrderContent> orderContents = new ArrayList<>();
        OrderContent orderContent = new OrderContent();
        orderContent.setOrderContentID(Identities.uuid2());
        orderContent.setOrderID(orderID);
        orderContent.setModifyDate(modifyDate);
        int commodityNum = activity.getNum() * banquetOrderReq.getNum();
        orderContent.setNum(commodityNum);
        orderContent.setPreorderNum(commodityNum);
        totalCommodityNum = +commodityNum;
        String commodityChannelID = activity.getCommodityChannelID();
        orderContent.setCommodityChannelID(commodityChannelID);
        
        CommodityChannel commodityChannel = iCommodityChannelService.findOne(commodityChannelID);
        
        Double commodityChannelPrise = commodityChannel.getCommodityChannelPrise();
        orderContent.setPrice(commodityChannelPrise);
        Double price = CalcUtil.mul(commodityChannelPrise, orderContent.getNum());
        orderContent.setTotalPrice(price);
        realPrice = CalcUtil.add(realPrice, price);
        
        CommodityTerminal commodityTerminal = getCommodityTerminal(
                String.valueOf(order.getOrderType()), commodityChannelID);
        if (!StringUtils.isEmpty(commodityTerminal.getConfigWarnMsg())) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, commodityTerminal.getConfigWarnMsg());
        }
        String terminalID = commodityTerminal.getCommodityTerminalID();
        orderContent.setCommodityTerminalID(terminalID);
        terminalNameMap.put(terminalID, commodityTerminal.getCommodityTerminalName());
        //记录订单商品的库存
        if (stockMap.containsKey(terminalID)) {
            stockMap.put(terminalID, stockMap.get(terminalID) + orderContent.getNum());
        } else {
            stockMap.put(terminalID, orderContent.getNum());
        }
        
        List<ActivityGift> activityGifts = activity.getActivityGifts();
        if (!org.springframework.util.CollectionUtils.isEmpty(activityGifts)) {
            List<ActivityGift> contentActivityGifts = new ArrayList<>();
            List<Gift> contentGifts = new ArrayList<>();
            for (ActivityGift activityGift : activityGifts) {
                ActivityGift cloneActivityGift = activityGift.clone();
                
                Gift gift = new Gift();
                gift.setGiftID(Identities.uuid2());
                
                gift.setModifyDate(System.currentTimeMillis());
                gift.setActivityID(activityGift.getActivityID());
                gift.setActivityGiftID(activityGift.getActivityGiftID());
                String giftTerminalID = activityGift.getCommodityTerminalID();
                gift.setCommodityTerminalID(giftTerminalID);
                CommodityTerminal giftTerminal = iCommodityTmlService.findOne(giftTerminalID);
                
                terminalNameMap.put(giftTerminalID, giftTerminal.getCommodityTerminalName());
                
                gift.setNum(activityGift.getNum() * banquetOrderReq.getNum());
                cloneActivityGift.setNum(gift.getNum());
                contentActivityGifts.add(cloneActivityGift);
                
                //记录赠品库存
                if (stockMap.containsKey(terminalID)) {
                    stockMap.put(terminalID, stockMap.get(terminalID) + orderContent.getNum());
                } else {
                    stockMap.put(terminalID, orderContent.getNum());
                }
                
                gift.setRelateType(GiftRelateType.订单内商品.getValue());
                gift.setRelateID(orderContent.getOrderContentID());
                gift.setOrderID(orderID);
                gift.setOrderContentID(orderContent.getOrderContentID());
                orderGiftNum += gift.getNum();
                contentGifts.add(gift);
            }
            orderContent.setActivityGifts(contentActivityGifts);
            orderContent.setGifts(contentGifts);
        }
        orderContents.add(orderContent);
        order.setOrderContents(orderContents);
        
        order.setCommodityNum(totalCommodityNum);
        order.setCommodityTotalNum(totalCommodityNum);
        order.setGiftNum(orderGiftNum);
        
        order.setRealPrice(realPrice);
        order.setActivityAmount(realPrice);
        order.setAmount(realPrice);
        order.setPayDiscounts(0.0);
        
        //生成订单编号
        String orderNO = generateOrderNO();
        order.setOrderNo(orderNO);
        
        if (!StringUtils.isEmpty(banquetOrderReq.getName()) || !StringUtils.isEmpty(banquetOrderReq.getMobile())) {
            Introducer introducer = new Introducer();
            introducer.setIntroducerID(Identities.uuid2());
            introducer.setName(banquetOrderReq.getName());
            introducer.setMobile(banquetOrderReq.getMobile());
            introducer.setOrderID(orderID);
            introducer.setModifyDate(modifyDate);
            order.setIntroducer(introducer);
        }
        
        boolean warningFlag = false;
        // 出库
        Iterator<Map.Entry<String, Integer>> iterator = stockMap.entrySet().iterator();
        //还货订单是减销售和客户的虚拟库存，其他都是只减一个库存，此处只减第一个，因为还货订单是新加了单独的接口
        String wareHouseID = buyer.getWarehouseID();
        while (iterator.hasNext()) {
            Map.Entry<String, Integer> entry = iterator.next();
            String commodityTerminalID = entry.getKey();
            Integer num = entry.getValue();
            Stock stock = iStockService.findByWarehouseIDAndCommodityTerminalID(wareHouseID, commodityTerminalID);
            if (stock != null) {
                if (stock.getNum() < num) {
                    logger.info(terminalNameMap.get(
                            commodityTerminalID) + "库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                    // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                    terminalMsgMap.put(commodityTerminalID, "库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                    warningFlag = true;
                }
            } else {
                logger.info(terminalNameMap.get(commodityTerminalID) + "库存不足，下单数量" + num + "，库存数量0");
                // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                terminalMsgMap.put(commodityTerminalID, "库存不足，下单数量" + num + "，库存数量0");
                warningFlag = true;
            }
        }
        
        if (warningFlag && orderConfig.isCheckStock()) {
            //先注释以下代码，不进行强制校验，需要前端配合 调试后放开
            String msg = "部分商品库存不足，请重新检查数量下单";
            if (OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
                msg = "业务员的库存中" + msg;
            }
            
            //处理订单正品和赠品库存不足提示语
            for (OrderContent content : order.getOrderContents()) {
                content.setStockLackMsg(terminalMsgMap.get(content.getCommodityTerminalID()));
                //处理订单赠品库存不足提示语
                if (CollectionUtils.isNotEmpty(content.getActivityGifts())) {
                    for (ActivityGift activityGift : content.getActivityGifts()) {
                        //活动赠品改为终端商品
                        activityGift.setStockLackMsg(terminalMsgMap.get(activityGift.getCommodityTerminalID()));
                    }
                }
            }
            
            return new ReturnBean<>(ResultCode.ERROR_SERVICE_NOT_ENOUGH.intValue(), msg, order);
        }
        
        order = save(order);
        
        //处理客户收货地址
        OrderReceivingAddr orderReceivingAddr = new OrderReceivingAddr();
        orderReceivingAddr.setOrderID(orderID);
        orderReceivingAddr.setReceivingAddrID(order.getCustomerUserID());
        orderReceivingAddr.setOrderReceivingAddrID(Identities.uuid2());
        orderReceivingAddr.setModifyDate(modifyDate);
        iOrderReceivingAddrService.save(orderReceivingAddr);
        
        return new ReturnBean<>(ResultCode.SUCCESS, "创建订单（宴会订单）成功", order);
    }
    
    /**
     * 修改宴会订单（宴会订单专用）
     *
     * @param order
     * @return
     */
    @Override
    public ReturnBean<Order> updateBanquetOrder(Order order) {
        // 宴会订单暂时不提供修改方法
        String orderID = order.getOrderID();
        Order dbOrder = findOne(orderID);
        if (null == dbOrder) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        
        if (OrderType.宴会订单.getValue().intValue() != order.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非宴会订单不可以修改订单");
        }
        
        //下单人校验
        if (!dbOrder.getBuyer().equals(order.getBuyer())) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "下单人信息不正确,不可以修改订单");
        }
        
        Long modifyDate = System.currentTimeMillis();
        order.setOrderID(orderID);
        order.setOrderCommitTime(modifyDate);
        order.setSalerID(order.getBuyer());
        
        order.setPlaceOrderType(PlaceOrderType.代客下单.getValue());
        order.setOrderType(OrderType.宴会订单.getValue());
        order.setStatus(OrderStatus.草稿.getValue());
    
        /*OrderReceivingAddr orderReceivingAddr = iOrderReceivingAddrService.findByOrderID(orderID);
        if(null != orderReceivingAddr && orderReceivingAddr.getReceivingAddrID().equals()){
        
        }*/
        
        return null;
    }
    
    /**
     * 删除宴会订单（宴会订单专用）
     *
     * @param orderID
     * @return
     */
    @Override
    public ReturnBean<String> deleteBanquetOrder(String orderID) {
        Order order = findOne(orderID);
        if (null == order) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        if (OrderType.宴会订单.getValue().intValue() != order.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非宴会订单不可以删除");
        }
        if (OrderStatus.订单提交_未支付.getValue().intValue() != order.getStatus()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非未支付状态的宴会订单不可以删除");
        }
        
        iGiftService.deleteByOrderID(orderID);
        iSaleOrderContentService.deleteByOrderID(orderID);
        delete(orderID);
        return new ReturnBean<>(ResultCode.SUCCESS, "删除成功");
    }
    
    @Override
    public ReturnBean<Order> decreaseStockForBanquetOrder(String orderID) {
        
        Order order = findOne(orderID);
        if (null == order) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        
        return decreaseStockForBanquetOrder(order);
    }
    
    private ReturnBean<Order> decreaseStockForBanquetOrder(Order order) {
        if (OrderType.宴会订单.getValue().intValue() != order.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非宴会订单不可以调用此接口");
        }
        
        User buyer = iUserService.findOne(order.getBuyer());
        
        Long modifyDate = System.currentTimeMillis();
        
        Map<String, Integer> stockMap = new HashMap<>();
        Map<String, String> terminalNameMap = new HashMap<>();
        Map<String, String> terminalMsgMap = new HashMap<>();
        
        List<OrderContent> orderContents = order.getOrderContents();
        if (!CollectionUtils.isEmpty(orderContents)) {
            for (OrderContent orderContent : orderContents) {
                String commodityTerminalID = orderContent.getCommodityTerminalID();
                if (stockMap.containsKey(commodityTerminalID)) {
                    stockMap.put(commodityTerminalID, stockMap.get(commodityTerminalID) + orderContent.getNum());
                } else {
                    stockMap.put(commodityTerminalID, orderContent.getNum());
                }
                List<Gift> gifts = orderContent.getGifts();
                if (!CollectionUtils.isEmpty(gifts)) {
                    for (Gift gift : gifts) {
                        String commodityTerminalID1 = gift.getCommodityTerminalID();
                        if (stockMap.containsKey(commodityTerminalID1)) {
                            stockMap.put(commodityTerminalID1, stockMap.get(commodityTerminalID1) + gift.getNum());
                        } else {
                            stockMap.put(commodityTerminalID1, gift.getNum());
                        }
                    }
                }
            }
        }
        
        boolean warningFlag = false;
        // 出库
        OutStock outStock = new OutStock();
        outStock.setOutStockID(Identities.uuid2());
        outStock.setWarehouseID(buyer.getWarehouseID());
        outStock.setOutStockType(OutStockType.订单出库.getValue());
        outStock.setProofID(order.getOrderID());
        outStock.setOutStocker(order.getBuyer());
        outStock.setModifyDate(modifyDate);
        List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
        Iterator<Map.Entry<String, Integer>> iterator = stockMap.entrySet().iterator();
        //减销售库存
        String wareHouseID = buyer.getWarehouseID();
        while (iterator.hasNext()) {
            Map.Entry<String, Integer> entry = iterator.next();
            String commodityTerminalID = entry.getKey();
            Integer num = entry.getValue();
            Stock stock = iStockService.findByWarehouseIDAndCommodityTerminalID(wareHouseID, commodityTerminalID);
            if (stock != null) {
                if (stock.getNum() >= entry.getValue()) {
                    OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails, commodityTerminalID, num);
                } else if (stock.getNum() < num) {
                    logger.info(terminalNameMap.get(
                            commodityTerminalID) + "库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                    // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                    terminalMsgMap.put(commodityTerminalID, "库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                    warningFlag = true;
                }
            } else {
                logger.info(terminalNameMap.get(commodityTerminalID) + "库存不足，下单数量" + num + "，库存数量0");
                // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                terminalMsgMap.put(commodityTerminalID, "库存不足，下单数量" + num + "，库存数量0");
                warningFlag = true;
            }
        }
        
        if (warningFlag && orderConfig.isCheckStock()) {
            String msg = "部分商品库存不足，请重新检查数量下单";
            if (OrderType.还货订单.getValue().intValue() == order.getOrderType()) {
                msg = "业务员的库存中" + msg;
            }
            
            //处理订单正品和赠品库存不足提示语
            for (OrderContent content : orderContents) {
                content.setStockLackMsg(terminalMsgMap.get(content.getCommodityTerminalID()));
                //处理订单赠品库存不足提示语
                if (CollectionUtils.isNotEmpty(content.getGifts())) {
                    for (Gift gift : content.getGifts()) {
                        gift.setStockLackMsg(terminalMsgMap.get(gift.getCommodityTerminalID()));
                    }
                }
            }
            return new ReturnBean<>(ResultCode.ERROR_SERVICE_NOT_ENOUGH.intValue(), msg, order);
        }
        
        outStock.setInOutStockDetails(inOutStockDetails);
        iStockService.addOutStock(outStock);
        return new ReturnBean<>(ResultCode.SUCCESS.intValue(), "减库存成功");
    }
    
    /**
     * 无款订单减库存
     *
     * @param orderID
     * @return
     */
    @Override
    public ReturnBean<Order> decreaseStockForNoMoneyOrder(String orderID) {
        Order order = findOne(orderID);
        if (null == order) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确");
        }
        
        if (OrderType.无款订单.getValue().intValue() != order.getOrderType()) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "非无款订单不可以调用此接口");
        }
        
        User buyer = iUserService.findOne(order.getBuyer());
        
        Long modifyDate = System.currentTimeMillis();
        //销售出库
        OutStock outStock = new OutStock();
        outStock.setOutStockType(OutStockType.订单出库.getValue());
        outStock.setProofID(orderID);
        outStock.setOutStocker(order.getBuyer());
        outStock.setWarehouseID(buyer.getWarehouseID());
        outStock.setModifyDate(modifyDate);
        
        List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
        
        for (OrderContent orderContent : order.getOrderContents()) {
            if (orderConfig.isCheckStock()) {
                // 得到销售或者店员的仓库ID，User表中已经处理好了，直接获取就是仓库ID
                String wareHouseID = buyer.getWarehouseID();
                //查询销售或者店员的库存，无款订单是销售和店员可以下单
                Stock stock = iStockService.findByWarehouseIDAndCommodityTerminalID(wareHouseID,
                        orderContent.getCommodityTerminalID());
                if (null == stock) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未查询到业务员（销售）相对的商品库存信息，请检查");
                }
                if (stock.getNum() < orderContent.getNum()) {
                    return new ReturnBean<>(ResultCode.ERROR_SERVICE, "商品数量超过业务员（销售）的库存数据，请检查");
                }
            }
            OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails, orderContent.getCommodityTerminalID(),
                    orderContent.getNum());
        }
        
        outStock.setInOutStockDetails(inOutStockDetails);
        iStockService.addOutStock(outStock);
        
        return new ReturnBean<>(ResultCode.SUCCESS.intValue(), "减库存成功");
    }
    
    private ReturnBean<Order> checkUserHasCreateOrderPermission(String buyerID) {
        // 检查下单人是否有该订单的权限
        List<Role> roles = iUserRoleService.findRolesByUserID(buyerID);
        if (CollectionUtils.isEmpty(roles)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "用户无相应角色信息，无下单权限");
        }
        
        Role buyerRole = roles.get(0);
        if (!(RoleEnum.店员.getValue().equals(buyerRole.getRoleID()) || RoleEnum.业务员.getValue().equals(
                buyerRole.getRoleID())
                || RoleEnum.团购专员.getValue().equals(buyerRole.getRoleID()))) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "用户无下单权限");
        }
        
        /*List<net.wofly.sale.order.domain.OrderType> orderTypes = iRoleOrderTypeService.findByRoleID(
                roles.get(0).getRoleID());
        if (CollectionUtils.isEmpty(orderTypes)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "用户无下单权限");
        }
        boolean canCreateOrder = false;
        for (net.wofly.sale.order.domain.OrderType orderType : orderTypes) {
            if (orderType.getOrderTypeID().equals(OrderType.无款订单.getValue().toString())) {
                canCreateOrder = true;
                break;
            }
        }
        if (!canCreateOrder) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "用户无下单权限");
        }*/
        return null;
    }
    
    
    @Override
    public List<Order> findToDoList(String userID) {
        List<Order> orders = iOrderFlowService.findToDoList(userID);
        
        if (CollectionUtils.isNotEmpty(orders)) {
            for (Order order : orders) {
                getOrderInfo(order);
            }
        }
        
        return orders;
    }
    
    @Override
    public ReturnBean<Order> getOrderForFlow(String orderID) {
        Order order = this.findOne(orderID);
        
        if (order == null) {
            return new ReturnBean<>(611, "业务工作流实例不存在");
        }
        
        if (order.getTaskID() == null) {
            return new ReturnBean<>(612, "业务工作流任务不存在");
        }
        
        getOrderInfoWithGifst(order);
        
        iOrderFlowService.getOrderForFlow(order);
        
        return new ReturnBean<>(0, "获取工作流信息成功", order);
    }
    
    @Override
    public ReturnBean<PageWrapper<Order>> getMyOrders(
            String userID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize) {
        
        //查到用户角色的得到是会员或者是员工
        List<Role> rolesByUserID = iUserRoleService.findRolesByUserID(userID);
        if (CollectionUtils.isEmpty(rolesByUserID)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未找到对应的用户角色");
        }
        
        if (rolesByUserID.get(0).getRoleID().startsWith("1")) {
            //员工
            return this.getSalerOrder(userID, orderNo, orderType, customerName, status, pageNum, pageSize);
        } else {
            //客户
            return this.getCustomerOrder(userID, pageNum, pageSize);
        }
    }
    
    @Override
    public List<Order> findByBuyerAndOrderCommitTimeBetween(String userID, Long startTime, Long endTime) {
        return saleOrderRepository.findByBuyerAndOrderCommitTimeBetween(userID, startTime, endTime);
    }
    
    @Override
    public List<Order> findByBuyerAndFinishedTimeBetween(String userID, Long startTime, Long endTime) {
        return saleOrderRepository.findByBuyerAndFinishedTimeBetween(userID, startTime, endTime);
    }
    
    @Override
    public List<Order> findByBuyerAndPayTimeBetween(String userID, Long startTime, Long endTime) {
        return saleOrderRepository.findByBuyerAndPayTimeBetween(userID, startTime, endTime);
    }
    
    /**
     * 检查订单是否有赠品（给工作流用，白条订单发货时，才进行减库存，如果有赠品，则继续调用减库存接口，反之则不调用）
     *
     * @param orderID
     * @return
     */
    @Override
    public boolean checkOrderHasGift(String orderID) {
        Order order = findOne(orderID);
        if (null == order) {
            return false;
        }
        if (order.getGifts() != null) {
            return true;
        }
        return false;
    }
    
    /**
     * 支付方式为白条订单的减库存（给工作流用）
     *
     * @param orderID
     * @return
     */
    @Override
    public ReturnBean<String> decreaseStockForBaiTiaoOrder(String orderID) {
        Order order = findOne(orderID);
        if (null == order) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "订单ID不正确！");
        }
        
        User buyer = iUserService.findOne(order.getBuyer());
        
        List<Role> roles = iUserRoleService.findRolesByUserID(order.getBuyer());
        
        //暂时考虑一个用户只有一个角色
        Role role = roles.get(0);
        
        //查询白条订单的赠品信息
        List<Gift> gifts = iGiftService.findByOrderID(orderID);
        if (CollectionUtils.isNotEmpty(gifts)) {
            boolean warningFlag = false;
            Long modifyDate = System.currentTimeMillis();
            String wareHouseIDs = getWarehouseID(order, buyer, role);
            
            Map<String, Integer> terminalStockMap = new HashMap<>();
            for (Gift gift : gifts) {
                String commodifyTerminalID = gift.getCommodityTerminalID();
                if (terminalStockMap.get(commodifyTerminalID) == null) {
                    terminalStockMap.put(commodifyTerminalID, gift.getNum());
                } else {
                    terminalStockMap.put(commodifyTerminalID, terminalStockMap.get(terminalStockMap) + gift.getNum());
                }
            }
            
            StringBuffer stockLackMsg = new StringBuffer();
            // 出库
            OutStock outStock = new OutStock();
            outStock.setOutStockID(Identities.uuid2());
            //还货订单是减销售和客户的虚拟库存，其他都是只减一个库存，此处只减第一个，因为还货订单是新加了单独的接口
            String wareHouseID = wareHouseIDs.split(COMMA_SIGN)[0];
            outStock.setWarehouseID(wareHouseIDs);
            outStock.setOutStockType(OutStockType.订单出库.getValue());
            outStock.setProofID(orderID);
            outStock.setOutStocker(order.getBuyer());
            outStock.setModifyDate(modifyDate);
            List<InOutStockDetail> inOutStockDetails = new ArrayList<>();
            
            Iterator<Map.Entry<String, Integer>> iterator = terminalStockMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Integer> entry = iterator.next();
                String commodityTerminalID = entry.getKey();
                Integer num = entry.getValue();
                Stock stock = iStockService.findByWarehouseIDAndCommodityTerminalID(wareHouseID, commodityTerminalID);
                if (stock != null) {
                    if (stock.getNum() >= entry.getValue()) {
                        OrderUtil.buildInOutStockDetailsObject(modifyDate, inOutStockDetails, commodityTerminalID, num);
                    } else if (stock.getNum() < num) {
                        logger.info("赠品库存不足，待发货赠品数量" + num + "，库存数量" + stock.getNum());
                        // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                        stockLackMsg.append("赠品库存不足，下单数量" + num + "，库存数量" + stock.getNum());
                        warningFlag = true;
                    }
                } else {
                    logger.info("库存不足，待发货赠品数量" + num + "，库存数量0");
                    // 库存不足时，正品和赠品都展示相同的提示语（下单数量m，库存数量n）
                    stockLackMsg.append("赠品库存不足，下单数量" + num + "，库存数量0");
                    warningFlag = true;
                }
            }
            
            if (warningFlag) {
                return new ReturnBean<>(ResultCode.ERROR_SERVICE_NOT_ENOUGH.intValue(), stockLackMsg.toString());
            }
            outStock.setInOutStockDetails(inOutStockDetails);
            iStockService.addOutStock(outStock);
        } else {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE_NOT_ENOUGH.intValue(), "订单无赠品，不需减库存");
        }
        return new ReturnBean<>(ResultCode.SUCCESS.intValue(), "减库存成功");
    }
    
    @Override
    public ReturnBean<PageWrapper<Order>> getMyOrdersByStatus(
            String userID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize) {
        //查到用户角色的得到是会员或者是员工
        List<Role> rolesByUserID = iUserRoleService.findRolesByUserID(userID);
        if (CollectionUtils.isEmpty(rolesByUserID)) {
            return new ReturnBean<>(ResultCode.ERROR_SERVICE, "未找到对应的用户角色");
        }
        
        if (rolesByUserID.get(0).getRoleID().startsWith("1")) {
            //员工
            return this.getSalerOrderByStatus(userID, orderNo, orderType, customerName, status, pageNum, pageSize);
        } else {
            //客户
            return this.getCustomerOrderByStatus(userID, status, pageNum, pageSize);
        }
    }
    
    private ReturnBean<PageWrapper<Order>> getSalerOrderByStatus(
            String salerID, String orderNo, Integer orderType, String customerName, Integer status, Integer pageNum,
            Integer pageSize) {
        if (iUserService.findOne(salerID) == null) {
            return new ReturnBean<PageWrapper<Order>>(ResultCode.ERROR_SERVICE, "销售员ID不正确");
        }
        
        Condition condition = new Condition();
        List<FilterCondition> filterConditions = new ArrayList<>();
        
        //判断customerID 是否是该销售员的客户
        //查询销售员的客户信息
        ReturnBean<PageWrapper<Order>> res = buildSalesFilterConditions(salerID, customerName, filterConditions);
        if (res != null) {
            return res;
        }
        
        if (!StringUtils.isEmpty(orderNo)) {
            filterConditions.add(
                    new FilterCondition(orderNo, "orderNo", ConditionRelate.and.name(), Operation.like.name(), 2));
        }
        if (orderType != null && orderType != -1) {
            filterConditions.add(new FilterCondition(String.valueOf(orderType), "orderType", ConditionRelate.and.name(),
                    Operation.eq.name(), 2));
        }
        
        //设置4种状态
        buildFilterConditon4Status(status, filterConditions);
        
        filterConditions.add(new FilterCondition(salerID, "salerID", ConditionRelate.and.name(),
                Operation.eq.name(), 1));
        
        condition.setFilterCondition(filterConditions);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), Order.class).getResult();
        
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.DESC, "orderCommitTime"));
        Page<Order> page = findAll(condition.getSpecification(), pageable);
        List<Order> orderList = page.getContent();
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                getOrderInfo(order);
            }
        }
        
        return new ReturnBean<>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    private ReturnBean<PageWrapper<Order>> buildSalesFilterConditions(
            String salerID, String customerName, List<FilterCondition> filterConditions) {
        List<String> customerIDS = new ArrayList<String>();
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(customerName)) {
            //  Q:需要确认是否只查询有效客户   A:查询所有客户，产生订单了都算
            if (customerName.length() == 32 && !GeneralHelper.isChinese(customerName)) {
                filterConditions.add(new FilterCondition(customerName, "customerUserID", ConditionRelate.and.name(),
                        Operation.eq.name(), 1));
            } else {
                List<User> users = null;
                if (GeneralHelper.isChinese(customerName)) {
                    users = iUserService.findByFollowUserIDAndNameLike(salerID, "%" + customerName + "%");
                } else {
                    users = iUserService.findByFollowUserIDAndNamePinYinLike(salerID, customerName + "%");
                }
                if (CollectionUtils.isEmpty(users)) {
                    Page page = new PageImpl(new ArrayList());
                    return new ReturnBean<PageWrapper<Order>>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
                }
                List<String> customerIDs = new ArrayList<>();
                for (User user : users) {
                    customerIDs.add(user.getUserID());
                }
                filterConditions.add(new FilterCondition(customerIDs, "customerUserID", ConditionRelate.and.name(),
                        Operation.in.name(), 1));
            }
        } else {
            //  Q:需要确认是否只查询有效客户   A:查询所有客户，产生订单了都算
            List<User> customerList = iUserService.findByFollowUserID(salerID);
            if (CollectionUtils.isNotEmpty(customerList)) {
                for (User customer : customerList) {
                    customerIDS.add(customer.getUserID());
                }
            }
        }
        return null;
    }
    
    
    private ReturnBean<PageWrapper<Order>> getCustomerOrderByStatus(
            String customerUserID, Integer status, Integer pageNum, Integer pageSize) {
        Condition condition = new Condition();
        List<FilterCondition> filterConditions = new ArrayList<FilterCondition>();
        filterConditions.add(new FilterCondition(customerUserID, "customerUserID", ConditionRelate.and.name(),
                Operation.eq.name(), 1));
        //设置4种状态
        buildFilterConditon4Status(status, filterConditions);
        
        condition.setFilterCondition(filterConditions);
        
        condition = ConditionUtil.buildCondition(XiNiaoJSON.toJSONString(condition), Order.class).getResult();
        
        Pageable pageable = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.DESC, "orderCommitTime"));
        Page<Order> page = findAll(condition.getSpecification(), pageable);
        List<Order> orderList = page.getContent();
        if (CollectionUtils.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                getOrderInfo(order);
            }
        }
        return new ReturnBean<PageWrapper<Order>>(ResultCode.SUCCESS, "查询成功", PageHelper.toPage(page));
    }
    
    private void buildFilterConditon4Status(Integer status, List<FilterCondition> filterConditions) {
        if (status != null) {
            if (status.intValue() == 9) {
                filterConditions.add(new FilterCondition(OrderStatus.订单取消1109.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.订单取消1409.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.订单取消1509.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
            } else if (status.intValue() == 1) {
                //待支付
                filterConditions.add(new FilterCondition(OrderStatus.订单提交_未支付.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.货到付款_未支付.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.支付定金.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
            } else if (status.intValue() == 2) {
                //已支付
                filterConditions.add(new FilterCondition(OrderStatus.白条已支付.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
                filterConditions.add(new FilterCondition(OrderStatus.订单己支付.getValue().toString(), "status",
                        ConditionRelate.or.name(), Operation.eq.name(), 20, 1, ConditionRelate.and.name()));
            }
        }
    }
}
